diff --git a/schemas/cache/.hashes.json b/schemas/cache/.hashes.json index 1b43218a..c92198b1 100644 --- a/schemas/cache/.hashes.json +++ b/schemas/cache/.hashes.json @@ -1,6 +1,6 @@ { - "https://adcontextprotocol.org/schemas/2.6.0/index.json": "730a1d6e729660a6c107842356f1fca6721d69027df7fb00d018a12a59515426", - "https://adcontextprotocol.org/schemas/2.6.0/adagents.json": "040822ddc5e53c07ddc6a144a6c4ca935048170d388981645c2a842bff5cba01", + "https://adcontextprotocol.org/schemas/2.6.0/index.json": "1537f09a2322b856d4ba9d8a3d6ad53410001aeaadd0787d2f18108114410d37", + "https://adcontextprotocol.org/schemas/2.6.0/adagents.json": "3f6f73cdc071a70029c360335e2172a36ad80873bcfa76f9e3222cbcfd81674e", "https://adcontextprotocol.org/schemas/2.6.0/core/activation-key.json": "bd518951d02618c71fbb7b986612e8eb407ff1e42e56e6425ff72fe62de6e398", "https://adcontextprotocol.org/schemas/2.6.0/core/assets/audio-asset.json": "8f58b0eaab323f37148586ca6c6053c3837beb1f4e11bd90643d65493906fd9b", "https://adcontextprotocol.org/schemas/2.6.0/core/assets/css-asset.json": "58b4d0e37c5c50de3aa0634e68782cb980243972effdbbbb031c9fed7909fcd6", @@ -30,6 +30,7 @@ "https://adcontextprotocol.org/schemas/2.6.0/core/format-id.json": "d9a14c1a435444d54c9f9367ae9c8c4e6587cb05f1548e98df3a003bc3aaf8bc", "https://adcontextprotocol.org/schemas/2.6.0/core/format.json": "9031bcb6669c5bb78692f50fa16641ccd99fd314e566275ef012468b2daca587", "https://adcontextprotocol.org/schemas/2.6.0/core/frequency-cap.json": "6a089fbfdbcdeb15f0f51341ddee9eb75e451ac03324b75bf3d6eb769f5964a1", + "https://adcontextprotocol.org/schemas/2.6.0/core/identifier.json": "0ab83432a7e5a4cf006e8e66e3daed37bb3762ced5e9c2bedf38a2f48864f98d", "https://adcontextprotocol.org/schemas/2.6.0/core/mcp-webhook-payload.json": "b70c73f858af7128459f5cec9ae6eca8cca7201c0b0c5390622de9626abf243e", "https://adcontextprotocol.org/schemas/2.6.0/core/measurement.json": "e69b4089087d788015d031db446ac96f338e1c1d404d26efc5e3d2333252552c", "https://adcontextprotocol.org/schemas/2.6.0/core/media-buy.json": "d63e59bb894cfc0229118b1c20165b10755016ac24042d3d3d0ef268947ce482", @@ -42,6 +43,7 @@ "https://adcontextprotocol.org/schemas/2.6.0/core/promoted-offerings.json": "89904b5f4ac756cbb1344024a9962ef0e7dbfa32c6fac59379cd2e5876ae96a1", "https://adcontextprotocol.org/schemas/2.6.0/core/promoted-products.json": "2e709fc90b776ece5907503ae83ca79af14dc0cc240a41782ddd9421aa13426f", "https://adcontextprotocol.org/schemas/2.6.0/core/property-id.json": "875cc214bd58ddd8d480a7a5c76776f07e7e834daed4dc2a099fbceb973bdb97", + "https://adcontextprotocol.org/schemas/2.6.0/core/property-list-ref.json": "fb08094a2e7de7840303bc62a31777109d810c2838be2040fd411fb36568556d", "https://adcontextprotocol.org/schemas/2.6.0/core/property-tag.json": "1a8a753226b02dbd359fb33abefb97dbdc13fd88b8eecf7321d5dd6d2942e6fe", "https://adcontextprotocol.org/schemas/2.6.0/core/property.json": "a7d1be9f0813386f0061174810170bcc64731c06e9e8e436fd888f880c8edd3f", "https://adcontextprotocol.org/schemas/2.6.0/core/protocol-envelope.json": "9a70425bdb28bbd69cf103f0826be514ba418f8186e244c22f6e0b5c2f966383", @@ -53,13 +55,13 @@ "https://adcontextprotocol.org/schemas/2.6.0/core/start-timing.json": "64ff8e6fae2b1cf490c2d274f13f66813b0c1b8e6ce051bd4c6adbfdf45c5488", "https://adcontextprotocol.org/schemas/2.6.0/core/sub-asset.json": "62cd6b334bb246504c927d7ef3e60b5d5624ae8d810fedb6301be87f710d3573", "https://adcontextprotocol.org/schemas/2.6.0/core/targeting.json": "af891f2c882f3975e4a4c2fd3d2e04796fa7a401f19dbc6e39f6a00308a6dd01", - "https://adcontextprotocol.org/schemas/2.6.0/creative/asset-types/index.json": "6cf91c2c2ffbccc2bb78a94c38a3cdb44624c4dda1b5e018efeddc3011dc3c83", + "https://adcontextprotocol.org/schemas/2.6.0/creative/asset-types/index.json": "389b7ff1ccd02d78a27e78a66dc05f9349a4213adf0fa022ac48d11ac1d61fbd", "https://adcontextprotocol.org/schemas/2.6.0/creative/list-creative-formats-request.json": "f45d84c60e795a69cd51bccea0c8f4a8aa265ae219d7207f411bf1a0342ace7f", "https://adcontextprotocol.org/schemas/2.6.0/creative/list-creative-formats-response.json": "a10637f93ab28ac03b78b8e5b5b8e129554ad907331695a766670b1d854d5fc2", "https://adcontextprotocol.org/schemas/2.6.0/creative/preview-creative-request.json": "4d1cda6561ce2ff645724076f10b70ff7b1e3b17655e660b12efdbffa6852584", "https://adcontextprotocol.org/schemas/2.6.0/creative/preview-creative-response.json": "1e7175be27ad98eb685e53ab6595796bad0950ea5425c4b8da45bfe20a9986b8", "https://adcontextprotocol.org/schemas/2.6.0/creative/preview-render.json": "b40d4e01eeb98942db2b9bf4802b78f6596295f8c7dbf0c3bac90b3e8bd4ec23", - "https://adcontextprotocol.org/schemas/2.6.0/enums/adcp-domain.json": "fb86b783d932ed188339b81c6e56782e930394b990508200d34d6b587e922903", + "https://adcontextprotocol.org/schemas/2.6.0/enums/adcp-domain.json": "ebcdc01f4c00aa50b156abc59d7d9f14674b01ccf935d8bf863ae5c517171b63", "https://adcontextprotocol.org/schemas/2.6.0/enums/asset-content-type.json": "a62ab210987be79ca430e0b40ddf91ae65db2bf83465470515d5c263f1dac2bb", "https://adcontextprotocol.org/schemas/2.6.0/enums/auth-scheme.json": "1a8e9be46cce2432d7f58be1888d140f9783f73bb97a20c10dfcf9070161d2f4", "https://adcontextprotocol.org/schemas/2.6.0/enums/available-metric.json": "b9beb1e79930ddd6d0f32ce41feee89ca10615fc61291d1f2227142fbfd47ddf", @@ -97,7 +99,7 @@ "https://adcontextprotocol.org/schemas/2.6.0/enums/sort-direction.json": "f1d72dfbdcff421cb81349b1c5209b5f6747b0d3a124f93ead7a325ba758309b", "https://adcontextprotocol.org/schemas/2.6.0/enums/standard-format-ids.json": "9fd7f60107a25be0a66bd57f8bb3aa82122f554ab185686a7eccbc753749c40d", "https://adcontextprotocol.org/schemas/2.6.0/enums/task-status.json": "7baa27e10078fec73b64b223170c39f3db89d818a82ad41ca9f02b6fd5c4b77b", - "https://adcontextprotocol.org/schemas/2.6.0/enums/task-type.json": "62ada0b15aaa8841a307f56e67f56a4d60a76eec6b698b9e58ba1e323862bf55", + "https://adcontextprotocol.org/schemas/2.6.0/enums/task-type.json": "3f0f97cfa6e8c11d3f352d4c6bdc67b1cb53ff03ff49d8ff3b9a1464af0df9ac", "https://adcontextprotocol.org/schemas/2.6.0/enums/update-frequency.json": "ada6745eb5c7edaebec2693478da6fd93fb807c48413332132b1d7df97e31688", "https://adcontextprotocol.org/schemas/2.6.0/enums/url-asset-type.json": "39e064861db8b50e41bef2dfa373f8309a2a14b27e65a93a6c3bb369d6f795f4", "https://adcontextprotocol.org/schemas/2.6.0/enums/validation-mode.json": "437dc25f290358d95ff5352fc26bdda5a992dfe8f04a191e16b2106e3d21071e", @@ -105,6 +107,8 @@ "https://adcontextprotocol.org/schemas/2.6.0/enums/vast-version.json": "5734bcc344af47e3ad4dcf68f155538614babaec7788326f5d82cec3129559ec", "https://adcontextprotocol.org/schemas/2.6.0/enums/webhook-response-type.json": "d81db53c78b4ae5ff32287746903ab9bbaf848859ef222dd9ed8d7c0ed17ed60", "https://adcontextprotocol.org/schemas/2.6.0/enums/webhook-security-method.json": "f74d763f720823948e5ade72a3a139e95675247e25a2671cfea6643d9a8f4872", + "https://adcontextprotocol.org/schemas/2.6.0/extensions/extension-meta.json": "1b4fc8ef344b08789514f86c2fa5d265cd47528e27b619aa5015ddaebd33075e", + "https://adcontextprotocol.org/schemas/2.6.0/extensions/index.json": "294f00ad72c90fb79810757cf23c1a770316a8fb9ef956da4a69483d5e5325ae", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/build-creative-request.json": "2633ac57f3a70c5ff82c2c240ca8066191d1778164c1415c4411593c9a7d4086", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/build-creative-response.json": "1b57abef495014331fe2e50a337048034c3b95d4a4e57c862664e40ce8a198d0", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/create-media-buy-async-response-input-required.json": "74c43004e366b5af309ebf2fcf2d757b181efe7124a09e36b09ea85a92fb3a86", @@ -117,15 +121,15 @@ "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-async-response-input-required.json": "00630687e7f8876e0fa14c14ad7f4989ce244b147cafdffe3089c62a062927eb", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-async-response-submitted.json": "1a02a09edfb86e4cbd677d161b1ee208427593b4e85c68930e565cf2b849dd30", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-async-response-working.json": "eab7913469420a43c9461e20bfe6bd057a139d49cfae08b59b71d7445cf0dab8", - "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-request.json": "ae9d2eda5dae9d5dd90e7835de153c097341a26ddd9f4c625fadefe13568cab0", - "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-response.json": "abdd7fc706a017bf37e52f354c9d6140d33ea422c999766797c6a02c04cfd013", + "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-request.json": "7c690fac3a26d4b6211661429a01edaa55ccb3c7b1eff6e7808ef91cbf271443", + "https://adcontextprotocol.org/schemas/2.6.0/media-buy/get-products-response.json": "501bf6f8aaaa18f7efe10a865612d56167e2b56196bd6daae29e59c781607f22", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-authorized-properties-request.json": "b13aa3eddcb4cb3e5efe64dca2dd520d5e83dfaa542587b5d88c360ddfa56178", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-authorized-properties-response.json": "11520ba350e4af718dbdb4f0122f3a4d9e278a460b4eeaffad265772446d43b3", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-creative-formats-request.json": "91990929c6c46a1d232bfb96a06d9ea9984b30de66d73d67a57744b7c3e90ad1", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-creative-formats-response.json": "9237034591d0c325367d9530ae843f809a7927424a9c3ffca42a96b3826e3803", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-creatives-request.json": "0788f951ff430c8cea3a012bd7c4ad64568385fa8f3ebf31e5930bad55702e09", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/list-creatives-response.json": "4ce8932d0a9d03a2d3268e486367f1b6e9bf8b8e4811fe54cb8b0cfd1ed9943a", - "https://adcontextprotocol.org/schemas/2.6.0/media-buy/package-request.json": "975a46e52e17f996bb2c07b8b65a8987e90b4c5bfa49300e8dca25e21edd1c8f", + "https://adcontextprotocol.org/schemas/2.6.0/media-buy/package-request.json": "b9670c860d2b3ee6e09bfd5d246b33f75ce8c36fd407a936edf0773be6533d3e", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/provide-performance-feedback-request.json": "a75a015151b0bb2dea2eb5a38b4277b5ce610c6f73a6e36985742d1ca155d905", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/provide-performance-feedback-response.json": "221b7abdf0ba2765e498cc26d3f0bd91457e38a0c721d845a07465f87340bbf1", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/sync-creatives-async-response-input-required.json": "e47eb69105a4c390b37a15c5097343d8b8a7491342e721bc7ddcab780de241de", @@ -136,7 +140,7 @@ "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-async-response-input-required.json": "ec4b8fedaeba9a5343a858b540a390703381f93f13ba6842cdf334f3d1ce300f", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-async-response-submitted.json": "61c4b236551201ce1f2af4be0f91b75dc3ab51731e282e3c9cd6cb74011b72de", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-async-response-working.json": "bda5f4df3faf1b0468ac2492b965bd20828a9fafa1c891b3673e68596c5d342e", - "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-request.json": "e53221c03588f26a8b2f7541564dc44c4e3b63813ae85964aac3b6ad8ab12b0b", + "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-request.json": "495f250df3f3fec67bcb8561ea84e55acddf2b376ce23d30778d2d391692a9d3", "https://adcontextprotocol.org/schemas/2.6.0/media-buy/update-media-buy-response.json": "19c8537f9f734363820f52a96fc815344fb9cb70eb8e3e88c73296297ffa5a68", "https://adcontextprotocol.org/schemas/2.6.0/pricing-options/cpc-option.json": "34c1a9b76b94065d48c9a5d45534ce81f088c7c3b385f783a8afca8b73da24c9", "https://adcontextprotocol.org/schemas/2.6.0/pricing-options/cpcv-option.json": "ea756831fda6ab8dcad3a1e1d956fe96733e11005926e871c5272050fb0f11fb", @@ -147,7 +151,27 @@ "https://adcontextprotocol.org/schemas/2.6.0/pricing-options/flat-rate-option.json": "2c100f26341acc170df6dd705754c45619be538cfdec790cf08dd8e8e6098d00", "https://adcontextprotocol.org/schemas/2.6.0/pricing-options/vcpm-auction-option.json": "6fe3ad592309cf85138b09c86703c212fe4d165fd60d0b6e52356eb17783d304", "https://adcontextprotocol.org/schemas/2.6.0/pricing-options/vcpm-fixed-option.json": "7b16a9382043bc7968d0c86db3ef513027bcc931f42550ca218b62e6e5c2e41a", - "https://adcontextprotocol.org/schemas/2.6.0/protocols/adcp-extension.json": "33836db34120b0b96c2b28a46b418b6ebb3f80a2fa80c5296f394c152f745147", + "https://adcontextprotocol.org/schemas/2.6.0/property/base-property-source.json": "8fc741ef7dc8c91edfc3d78802a7bdd2066a46a49b8ad68a8a7a8380085d0bee", + "https://adcontextprotocol.org/schemas/2.6.0/property/create-property-list-request.json": "5526ea26f57c711588e68751dd07775e1d96d4eea16e42ba600520b171cf07e8", + "https://adcontextprotocol.org/schemas/2.6.0/property/create-property-list-response.json": "0699046c948ce95337af76e2f152ec088ae125b829fc06c1d47e829c621ab528", + "https://adcontextprotocol.org/schemas/2.6.0/property/delete-property-list-request.json": "05b691930949c8a037795b3cfb5866c017669c205ad5fa22d8eefab40c824067", + "https://adcontextprotocol.org/schemas/2.6.0/property/delete-property-list-response.json": "d60093f095905dceaff553eab0dd3356202bfb1d6b96fa7c20195996ba66db82", + "https://adcontextprotocol.org/schemas/2.6.0/property/feature-requirement.json": "d46f3d3c74be646f52102524f5b3c162069af20c42eb025885ee6e965f3b9acc", + "https://adcontextprotocol.org/schemas/2.6.0/property/get-property-list-request.json": "604073eaf53a68d8a16204a28a2468592c19b267950d5fce4e1e3671b3e3246f", + "https://adcontextprotocol.org/schemas/2.6.0/property/get-property-list-response.json": "3410564dc6a05475dd46ba9ad4ddb2c78c40ebfddf1e6f139e4e30fe43932897", + "https://adcontextprotocol.org/schemas/2.6.0/property/list-property-features-request.json": "e53044fb80952bc2de02fc71bc3143563c6b50183e6a18b060b7b493ca2ca8b0", + "https://adcontextprotocol.org/schemas/2.6.0/property/list-property-features-response.json": "1a9b61a83176e8cfe1cffc13cd06b0ac4d6a383ca08d5c0ea601f421cf327707", + "https://adcontextprotocol.org/schemas/2.6.0/property/list-property-lists-request.json": "216874121f7efb29daaea1aae44bb21c25cc4819a3ab6c7e4fa97b8868c0b31c", + "https://adcontextprotocol.org/schemas/2.6.0/property/list-property-lists-response.json": "93e16d4819fcd299ac2ced111455afe2509dfabc0edce0127bf236fa1d917e6c", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-error.json": "fb15030e22d36039fb579d16ce911076d678fdd92e6e234a5f55e4b02872d267", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-feature-definition.json": "512640079410580aabb43f2526e7e0741511f0297730088bddfc5ffaf53f9d4b", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-feature.json": "b1d8d1c033292e265b3314b1a3cc826bb3cbf4ff63921b3c8597bcd6521bb3c1", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-list-changed-webhook.json": "af5f96b649c98a879d3d12f6068c060fb2e31a82a39fcd4e86fdd60ba79793ea", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-list-filters.json": "0a122f5ece612f15e1fd3f37d70b916c3dffb89a697a83f94e011464a7649598", + "https://adcontextprotocol.org/schemas/2.6.0/property/property-list.json": "a79fbddeca1b5b3ff2dfe7eb02a6db4e4125da356fe6a9b68489a344f7404efa", + "https://adcontextprotocol.org/schemas/2.6.0/property/update-property-list-request.json": "b3831277ca98805fbb3ba9ea6aceeb54d6b1694ff470a770feaae6897aeb4054", + "https://adcontextprotocol.org/schemas/2.6.0/property/update-property-list-response.json": "08983661fd168907f4899d1f972c064fd192684d3cf93bfae57289b28d19c084", + "https://adcontextprotocol.org/schemas/2.6.0/protocols/adcp-extension.json": "72f179773a44305914c7439f7a47a209c2294b08087b157210a42da0a8eacb23", "https://adcontextprotocol.org/schemas/2.6.0/signals/activate-signal-request.json": "afa9b3023801fe0589e6bf54c26f9df0dda30362dcf5d59c90693db4f2b7c55a", "https://adcontextprotocol.org/schemas/2.6.0/signals/activate-signal-response.json": "6710d1ee820f9f887ceaf34cbafffc5cc93441caeaaf9a3cc91742ad60c00d52", "https://adcontextprotocol.org/schemas/2.6.0/signals/get-signals-request.json": "2df5b4b6e1eed5a5df373a255cda5549bd84eb1dca9a1bb4a5449656be2992ea", diff --git a/schemas/cache/adagents.json b/schemas/cache/adagents.json index d1511248..0097e626 100644 --- a/schemas/cache/adagents.json +++ b/schemas/cache/adagents.json @@ -218,6 +218,81 @@ "name": "Example Third-Party Sales Agent" }, "last_updated": "2025-01-10T17:00:00Z" + }, + { + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ + { + "authorization_type": "property_tags", + "authorized_for": "All news properties", + "property_tags": [ + "news" + ], + "url": "https://sales.news.example.com" + } + ], + "contact": { + "domain": "news.example.com", + "email": "adops@news.example.com", + "name": "Premium News Publisher" + }, + "last_updated": "2025-01-10T18:00:00Z", + "properties": [ + { + "identifiers": [ + { + "type": "domain", + "value": "news.example.com" + } + ], + "name": "News Example", + "property_type": "website", + "publisher_domain": "news.example.com", + "tags": [ + "premium", + "news" + ] + } + ], + "property_features": [ + { + "features": [ + "carbon_score", + "sustainability_grade" + ], + "name": "Scope3", + "publisher_id": "pub_news_12345", + "url": "https://api.scope3.com" + }, + { + "features": [ + "tag_certified_against_fraud", + "tag_brand_safety_certified" + ], + "name": "TAG", + "url": "https://api.tagtoday.net" + }, + { + "features": [ + "gdpr_compliant", + "tcf_registered", + "ccpa_compliant" + ], + "name": "OneTrust", + "publisher_id": "ot_news_67890", + "url": "https://api.onetrust.com" + } + ], + "tags": { + "news": { + "description": "News and journalism content", + "name": "News Properties" + }, + "premium": { + "description": "High-quality, brand-safe properties", + "name": "Premium Properties" + } + } } ], "oneOf": [ @@ -460,6 +535,42 @@ "minItems": 1, "type": "array" }, + "property_features": { + "description": "[AdCP 3.0] Optional list of agents that provide property feature data (certifications, scores, compliance status). Used for discovery - actual data comes from querying the agent's get_property_features task.", + "items": { + "additionalProperties": true, + "properties": { + "features": { + "description": "Feature IDs this agent provides (e.g., 'carbon_score', 'tag_certified_against_fraud'). Use list_property_features on the agent for full definitions.", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "name": { + "description": "Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')", + "type": "string" + }, + "publisher_id": { + "description": "Optional publisher identifier at this agent (for lookup)", + "type": "string" + }, + "url": { + "description": "The agent's API endpoint URL (must implement get_property_features)", + "format": "uri", + "type": "string" + } + }, + "required": [ + "url", + "name", + "features" + ], + "type": "object" + }, + "type": "array" + }, "tags": { "additionalProperties": { "additionalProperties": true, diff --git a/schemas/cache/core/identifier.json b/schemas/cache/core/identifier.json new file mode 100644 index 00000000..d3e2af46 --- /dev/null +++ b/schemas/cache/core/identifier.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "A property identifier with type and value. Used to identify properties across platforms (domains, app store IDs, etc.).", + "properties": { + "type": { + "$ref": "../enums/identifier-types.json", + "description": "Type of identifier" + }, + "value": { + "description": "The identifier value. For domain type: 'example.com' matches base domain plus www and m subdomains; 'edition.example.com' matches that specific subdomain; '*.example.com' matches ALL subdomains but NOT base domain", + "type": "string" + } + }, + "required": [ + "type", + "value" + ], + "title": "Identifier", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/core/property-list-ref.json b/schemas/cache/core/property-list-ref.json new file mode 100644 index 00000000..7f374877 --- /dev/null +++ b/schemas/cache/core/property-list-ref.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Reference to an externally managed property list. Enables passing large property sets (50,000+) without embedding them in requests. The receiving agent fetches and caches the list independently.", + "properties": { + "agent_url": { + "description": "URL of the agent managing the property list", + "format": "uri", + "type": "string" + }, + "auth_token": { + "description": "JWT or other authorization token for accessing the list. Optional if the list is public or caller has implicit access.", + "type": "string" + }, + "list_id": { + "description": "Identifier for the property list within the agent", + "minLength": 1, + "type": "string" + } + }, + "required": [ + "agent_url", + "list_id" + ], + "title": "Property List Reference", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/creative/asset-types/index.json b/schemas/cache/creative/asset-types/index.json index e29da17b..92edacd6 100644 --- a/schemas/cache/creative/asset-types/index.json +++ b/schemas/cache/creative/asset-types/index.json @@ -91,7 +91,7 @@ }, "baseUrl": "/schemas/2.6.0", "description": "Registry of asset types used in AdCP creative manifests. Each asset type defines the structure of actual content payloads (what you send), not requirements or constraints (which belong in format specifications).", - "lastUpdated": "2026-01-07", + "lastUpdated": "2026-01-13", "title": "AdCP Asset Type Registry", "usage_notes": { "creative_manifests": "Creative manifests provide actual asset content, keyed by asset_id from the format. Asset type is determined by the format specification, not declared in the payload.", diff --git a/schemas/cache/enums/adcp-domain.json b/schemas/cache/enums/adcp-domain.json index 26159b95..b8c44f45 100644 --- a/schemas/cache/enums/adcp-domain.json +++ b/schemas/cache/enums/adcp-domain.json @@ -3,8 +3,16 @@ "description": "AdCP protocol domains for task categorization", "enum": [ "media-buy", - "signals" + "signals", + "governance", + "creative" ], + "enumDescriptions": { + "creative": "Creative asset management, format discovery, and rendering", + "governance": "Property governance (identity, authorization, data, selection), brand standards, and compliance", + "media-buy": "Campaign creation, package management, and delivery optimization", + "signals": "Audience signal discovery and activation" + }, "title": "AdCP Domain", "type": "string" } \ No newline at end of file diff --git a/schemas/cache/enums/task-type.json b/schemas/cache/enums/task-type.json index 7ce8fe9a..0bbdca91 100644 --- a/schemas/cache/enums/task-type.json +++ b/schemas/cache/enums/task-type.json @@ -6,18 +6,30 @@ "update_media_buy", "sync_creatives", "activate_signal", - "get_signals" + "get_signals", + "list_property_features", + "create_property_list", + "update_property_list", + "get_property_list", + "list_property_lists", + "delete_property_list" ], "enumDescriptions": { "activate_signal": "Signals domain: Activate an audience signal on a specific platform or account", "create_media_buy": "Media-buy domain: Create a new advertising campaign with one or more packages", + "create_property_list": "Property domain: Create a new property list with filters and brand manifest", + "delete_property_list": "Property domain: Delete a property list", + "get_property_list": "Property domain: Retrieve a property list with resolved properties", "get_signals": "Signals domain: Discover available audience signals based on natural language description", + "list_property_features": "Property domain: Discover what features a governance agent can evaluate", + "list_property_lists": "Property domain: List all accessible property lists", "sync_creatives": "Media-buy domain: Sync creative assets to publisher's library with upsert semantics", - "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters" + "update_media_buy": "Media-buy domain: Update campaign settings, package configuration, or delivery parameters", + "update_property_list": "Property domain: Update an existing property list" }, "notes": [ "Task types map to specific AdCP task operations", - "Each task type belongs to either the 'media-buy' or 'signals' domain", + "Each task type belongs to the 'media-buy', 'signals', 'property', or 'creative' domain", "This enum is used in task management APIs (tasks/list, tasks/get) and webhook payloads", "New task types require a minor version bump per semantic versioning" ], diff --git a/schemas/cache/extensions/extension-meta.json b/schemas/cache/extensions/extension-meta.json new file mode 100644 index 00000000..26ae70f0 --- /dev/null +++ b/schemas/cache/extensions/extension-meta.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "Schema that all extension files must follow. Combines metadata (valid_from, docs_url) with the actual extension data schema. Extensions are auto-discovered from /schemas/extensions/*.json and included in versioned builds based on valid_from/valid_until.", + "properties": { + "$schema": { + "const": "http://json-schema.org/draft-07/schema#", + "type": "string" + }, + "additionalProperties": { + "description": "Whether additional properties are allowed in the extension data" + }, + "description": { + "description": "Description of what this extension provides", + "type": "string" + }, + "docs_url": { + "description": "URL to documentation for implementors of this extension", + "format": "uri", + "type": "string" + }, + "properties": { + "additionalProperties": true, + "description": "Schema properties defining the structure of ext.{namespace} data", + "type": "object" + }, + "required": { + "description": "Required properties within the extension data", + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "description": "Human-readable title for the extension", + "type": "string" + }, + "type": { + "const": "object", + "description": "Extensions must be objects (data within ext.{namespace})" + }, + "valid_from": { + "description": "Minimum AdCP version this extension is compatible with (e.g., '2.5'). Extension will be included in all versioned schema builds >= this version.", + "pattern": "^\\d+\\.\\d+$", + "type": "string" + }, + "valid_until": { + "description": "Last AdCP version this extension is compatible with (e.g., '3.0'). Omit if extension is still valid for current and future versions.", + "pattern": "^\\d+\\.\\d+$", + "type": "string" + } + }, + "required": [ + "$schema", + "$id", + "title", + "description", + "valid_from", + "type", + "properties" + ], + "title": "AdCP Extension File Schema", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/extensions/index.json b/schemas/cache/extensions/index.json new file mode 100644 index 00000000..9db856bd --- /dev/null +++ b/schemas/cache/extensions/index.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "_generated": true, + "_generatedAt": "2026-01-13T23:32:36.210Z", + "description": "Auto-generated registry of formal AdCP extensions. Extensions provide typed schemas for vendor-specific or domain-specific data within the ext field. Agents declare which extensions they support in their agent card.", + "extensions": {}, + "title": "AdCP Extension Registry" +} \ No newline at end of file diff --git a/schemas/cache/media-buy/get-products-request.json b/schemas/cache/media-buy/get-products-request.json index 1896428c..dd50040d 100644 --- a/schemas/cache/media-buy/get-products-request.json +++ b/schemas/cache/media-buy/get-products-request.json @@ -19,6 +19,10 @@ }, "filters": { "$ref": "../core/product-filters.json" + }, + "property_list": { + "$ref": "../core/property-list-ref.json", + "description": "[AdCP 3.0] Reference to an externally managed property list. When provided, the sales agent should filter products to only those available on properties in the list." } }, "required": [], diff --git a/schemas/cache/media-buy/get-products-response.json b/schemas/cache/media-buy/get-products-response.json index ee961efa..b0cbc817 100644 --- a/schemas/cache/media-buy/get-products-response.json +++ b/schemas/cache/media-buy/get-products-response.json @@ -22,6 +22,10 @@ "$ref": "../core/product.json" }, "type": "array" + }, + "property_list_applied": { + "description": "[AdCP 3.0] Indicates whether property_list filtering was applied. True if the agent filtered products based on the provided property_list. Absent or false if property_list was not provided or not supported by this agent.", + "type": "boolean" } }, "required": [ diff --git a/schemas/cache/media-buy/package-request.json b/schemas/cache/media-buy/package-request.json index 09002e63..f56c2295 100644 --- a/schemas/cache/media-buy/package-request.json +++ b/schemas/cache/media-buy/package-request.json @@ -43,9 +43,19 @@ "minItems": 1, "type": "array" }, + "impressions": { + "description": "Impression goal for this package", + "minimum": 0, + "type": "number" + }, "pacing": { "$ref": "../enums/pacing.json" }, + "paused": { + "default": false, + "description": "Whether this package should be created in a paused state. Paused packages do not deliver impressions. Defaults to false.", + "type": "boolean" + }, "pricing_option_id": { "description": "ID of the selected pricing option from the product's pricing_options array", "type": "string" diff --git a/schemas/cache/media-buy/update-media-buy-request.json b/schemas/cache/media-buy/update-media-buy-request.json index 86d97717..f8af4146 100644 --- a/schemas/cache/media-buy/update-media-buy-request.json +++ b/schemas/cache/media-buy/update-media-buy-request.json @@ -87,6 +87,11 @@ "maxItems": 100, "type": "array" }, + "impressions": { + "description": "Updated impression goal for this package", + "minimum": 0, + "type": "number" + }, "pacing": { "$ref": "../enums/pacing.json" }, diff --git a/schemas/cache/property/base-property-source.json b/schemas/cache/property/base-property-source.json new file mode 100644 index 00000000..8b06a93b --- /dev/null +++ b/schemas/cache/property/base-property-source.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "A source of properties for a property list. Supports three selection patterns: publisher with tags, publisher with property IDs, or direct identifiers.", + "discriminator": { + "propertyName": "selection_type" + }, + "oneOf": [ + { + "additionalProperties": false, + "description": "Select properties from a publisher by tag membership", + "properties": { + "publisher_domain": { + "description": "Domain where publisher's adagents.json is hosted (e.g., 'raptive.com')", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", + "type": "string" + }, + "selection_type": { + "const": "publisher_tags", + "description": "Discriminator indicating selection by property tags within a publisher", + "type": "string" + }, + "tags": { + "description": "Property tags from the publisher's adagents.json. Selects all properties with these tags.", + "items": { + "$ref": "../core/property-tag.json" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "selection_type", + "publisher_domain", + "tags" + ], + "title": "Publisher Tags Source", + "type": "object" + }, + { + "additionalProperties": false, + "description": "Select specific properties from a publisher by ID", + "properties": { + "property_ids": { + "description": "Specific property IDs from the publisher's adagents.json", + "items": { + "$ref": "../core/property-id.json" + }, + "minItems": 1, + "type": "array" + }, + "publisher_domain": { + "description": "Domain where publisher's adagents.json is hosted (e.g., 'raptive.com')", + "pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", + "type": "string" + }, + "selection_type": { + "const": "publisher_ids", + "description": "Discriminator indicating selection by specific property IDs within a publisher", + "type": "string" + } + }, + "required": [ + "selection_type", + "publisher_domain", + "property_ids" + ], + "title": "Publisher Property IDs Source", + "type": "object" + }, + { + "additionalProperties": false, + "description": "Select properties by direct identifiers (domains, app IDs, etc.) without publisher context", + "properties": { + "identifiers": { + "description": "Direct property identifiers (domains, app IDs, etc.)", + "items": { + "$ref": "../core/identifier.json" + }, + "minItems": 1, + "type": "array" + }, + "selection_type": { + "const": "identifiers", + "description": "Discriminator indicating selection by direct identifiers", + "type": "string" + } + }, + "required": [ + "selection_type", + "identifiers" + ], + "title": "Direct Identifiers Source", + "type": "object" + } + ], + "title": "Base Property Source" +} \ No newline at end of file diff --git a/schemas/cache/property/create-property-list-request.json b/schemas/cache/property/create-property-list-request.json new file mode 100644 index 00000000..55740a15 --- /dev/null +++ b/schemas/cache/property/create-property-list-request.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request parameters for creating a new property list", + "properties": { + "base_properties": { + "description": "Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database.", + "items": { + "$ref": "base-property-source.json" + }, + "type": "array" + }, + "brand_manifest": { + "$ref": "../core/brand-manifest.json", + "description": "Brand identity and requirements. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.)." + }, + "context": { + "$ref": "../core/context.json" + }, + "description": { + "description": "Description of the list's purpose", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "filters": { + "$ref": "property-list-filters.json", + "description": "Dynamic filters to apply when resolving the list" + }, + "name": { + "description": "Human-readable name for the list", + "type": "string" + } + }, + "required": [ + "name" + ], + "title": "Create Property List Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/create-property-list-response.json b/schemas/cache/property/create-property-list-response.json new file mode 100644 index 00000000..1f0762f2 --- /dev/null +++ b/schemas/cache/property/create-property-list-response.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for create_property_list task", + "properties": { + "auth_token": { + "description": "Token that can be shared with sellers to authorize fetching this list. Store this - it is only returned at creation time.", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "list": { + "$ref": "property-list.json", + "description": "The created property list" + } + }, + "required": [ + "list", + "auth_token" + ], + "title": "Create Property List Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/delete-property-list-request.json b/schemas/cache/property/delete-property-list-request.json new file mode 100644 index 00000000..68d21c4e --- /dev/null +++ b/schemas/cache/property/delete-property-list-request.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request parameters for deleting a property list", + "properties": { + "context": { + "$ref": "../core/context.json" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "list_id": { + "description": "ID of the property list to delete", + "type": "string" + } + }, + "required": [ + "list_id" + ], + "title": "Delete Property List Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/delete-property-list-response.json b/schemas/cache/property/delete-property-list-response.json new file mode 100644 index 00000000..f457ee5c --- /dev/null +++ b/schemas/cache/property/delete-property-list-response.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for delete_property_list task", + "properties": { + "deleted": { + "description": "Whether the list was successfully deleted", + "type": "boolean" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "list_id": { + "description": "ID of the deleted list", + "type": "string" + } + }, + "required": [ + "deleted", + "list_id" + ], + "title": "Delete Property List Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/feature-requirement.json b/schemas/cache/property/feature-requirement.json new file mode 100644 index 00000000..91573b15 --- /dev/null +++ b/schemas/cache/property/feature-requirement.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "A feature-based requirement for property filtering. Use min_value/max_value for quantitative features, allowed_values for binary/categorical features.", + "properties": { + "allowed_values": { + "description": "Values that pass the requirement (for binary/categorical features)", + "items": {}, + "type": "array" + }, + "feature_id": { + "description": "Feature to evaluate (discovered via list_property_features)", + "type": "string" + }, + "if_not_covered": { + "default": "exclude", + "description": "How to handle properties where this feature is not covered. 'exclude' (default): property is removed from the list. 'include': property passes this requirement (fail-open).", + "enum": [ + "exclude", + "include" + ], + "type": "string" + }, + "max_value": { + "description": "Maximum numeric value allowed (for quantitative features)", + "type": "number" + }, + "min_value": { + "description": "Minimum numeric value required (for quantitative features)", + "type": "number" + } + }, + "required": [ + "feature_id" + ], + "title": "Feature Requirement", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/get-property-list-request.json b/schemas/cache/property/get-property-list-request.json new file mode 100644 index 00000000..7b1d3395 --- /dev/null +++ b/schemas/cache/property/get-property-list-request.json @@ -0,0 +1,36 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request parameters for retrieving a property list with resolved identifiers", + "properties": { + "context": { + "$ref": "../core/context.json" + }, + "cursor": { + "description": "Pagination cursor for large result sets", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "list_id": { + "description": "ID of the property list to retrieve", + "type": "string" + }, + "max_results": { + "description": "Maximum identifiers to return (for large lists)", + "minimum": 1, + "type": "integer" + }, + "resolve": { + "default": true, + "description": "Whether to apply filters and return resolved identifiers (default: true)", + "type": "boolean" + } + }, + "required": [ + "list_id" + ], + "title": "Get Property List Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/get-property-list-response.json b/schemas/cache/property/get-property-list-response.json new file mode 100644 index 00000000..7eb7365e --- /dev/null +++ b/schemas/cache/property/get-property-list-response.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for get_property_list task. Returns identifiers only (not full property objects or scores). Consumers should cache the resolved identifiers and refresh based on cache_valid_until.", + "properties": { + "cache_valid_until": { + "description": "Cache expiration timestamp. Re-fetch the list after this time to get updated identifiers.", + "format": "date-time", + "type": "string" + }, + "coverage_gaps": { + "additionalProperties": { + "items": { + "$ref": "../core/identifier.json" + }, + "type": "array" + }, + "description": "Properties included in the list despite missing feature data. Only present when a feature_requirement has if_not_covered='include'. Maps feature_id to list of identifiers not covered for that feature.", + "type": "object" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "identifiers": { + "description": "Resolved identifiers that passed filters (if resolve=true). Cache these locally for real-time use.", + "items": { + "$ref": "../core/identifier.json" + }, + "type": "array" + }, + "list": { + "$ref": "property-list.json", + "description": "The property list metadata (always returned)" + }, + "pagination": { + "additionalProperties": false, + "description": "Pagination information", + "properties": { + "cursor": { + "description": "Cursor for next page", + "type": "string" + }, + "has_more": { + "description": "Whether more results are available", + "type": "boolean" + } + }, + "type": "object" + }, + "resolved_at": { + "description": "When the list was resolved", + "format": "date-time", + "type": "string" + }, + "returned_count": { + "description": "Number of identifiers returned in this response", + "type": "integer" + }, + "total_count": { + "description": "Total number of identifiers in resolved list", + "type": "integer" + } + }, + "required": [ + "list" + ], + "title": "Get Property List Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/list-property-features-request.json b/schemas/cache/property/list-property-features-request.json new file mode 100644 index 00000000..4dcf8c47 --- /dev/null +++ b/schemas/cache/property/list-property-features-request.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request payload for list_property_features task. Discovers what features a governance agent can evaluate.", + "properties": { + "countries": { + "description": "Filter to features available in these countries", + "items": { + "type": "string" + }, + "type": "array" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "property_types": { + "description": "Filter to features available for these property types", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "title": "List Property Features Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/list-property-features-response.json b/schemas/cache/property/list-property-features-response.json new file mode 100644 index 00000000..17717e14 --- /dev/null +++ b/schemas/cache/property/list-property-features-response.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for list_property_features task. Returns the features this governance agent can evaluate.", + "properties": { + "ext": { + "$ref": "../core/ext.json" + }, + "features": { + "description": "Features this agent can evaluate", + "items": { + "$ref": "property-feature-definition.json" + }, + "type": "array" + } + }, + "required": [ + "features" + ], + "title": "List Property Features Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/list-property-lists-request.json b/schemas/cache/property/list-property-lists-request.json new file mode 100644 index 00000000..feacc64d --- /dev/null +++ b/schemas/cache/property/list-property-lists-request.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request parameters for listing property lists", + "properties": { + "context": { + "$ref": "../core/context.json" + }, + "cursor": { + "description": "Pagination cursor", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "max_results": { + "default": 100, + "description": "Maximum lists to return", + "minimum": 1, + "type": "integer" + }, + "name_contains": { + "description": "Filter to lists whose name contains this string", + "type": "string" + }, + "principal": { + "description": "Filter to lists owned by this principal", + "type": "string" + } + }, + "title": "List Property Lists Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/list-property-lists-response.json b/schemas/cache/property/list-property-lists-response.json new file mode 100644 index 00000000..9a6eb556 --- /dev/null +++ b/schemas/cache/property/list-property-lists-response.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for list_property_lists task", + "properties": { + "ext": { + "$ref": "../core/ext.json" + }, + "lists": { + "description": "Array of property lists (metadata only, not resolved properties)", + "items": { + "$ref": "property-list.json" + }, + "type": "array" + }, + "pagination": { + "additionalProperties": false, + "description": "Pagination information", + "properties": { + "cursor": { + "description": "Cursor for next page", + "type": "string" + }, + "has_more": { + "description": "Whether more results are available", + "type": "boolean" + } + }, + "type": "object" + }, + "returned_count": { + "description": "Number of lists returned in this response", + "type": "integer" + }, + "total_count": { + "description": "Total number of lists matching criteria", + "type": "integer" + } + }, + "required": [ + "lists" + ], + "title": "List Property Lists Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-error.json b/schemas/cache/property/property-error.json new file mode 100644 index 00000000..efccf90f --- /dev/null +++ b/schemas/cache/property/property-error.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Error information for a property that could not be evaluated", + "properties": { + "code": { + "description": "Error code", + "enum": [ + "PROPERTY_NOT_FOUND", + "PROPERTY_NOT_MONITORED", + "LIST_NOT_FOUND", + "LIST_ACCESS_DENIED", + "METHODOLOGY_NOT_SUPPORTED", + "JURISDICTION_NOT_SUPPORTED" + ], + "type": "string" + }, + "message": { + "description": "Human-readable error message", + "type": "string" + }, + "property": { + "$ref": "../core/property.json", + "description": "The property that caused the error" + } + }, + "required": [ + "code", + "message" + ], + "title": "Property Error", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-feature-definition.json b/schemas/cache/property/property-feature-definition.json new file mode 100644 index 00000000..703cd3c6 --- /dev/null +++ b/schemas/cache/property/property-feature-definition.json @@ -0,0 +1,95 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Defines a feature that a governance agent can evaluate for properties. Used in list_property_features to advertise agent capabilities.", + "properties": { + "allowed_values": { + "description": "For categorical features, the set of valid values", + "items": { + "type": "string" + }, + "type": "array" + }, + "coverage": { + "additionalProperties": false, + "description": "What this feature covers (empty arrays = all)", + "properties": { + "countries": { + "description": "Countries where this feature is available", + "items": { + "type": "string" + }, + "type": "array" + }, + "property_types": { + "description": "Property types this feature applies to", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "description": { + "description": "Description of what this feature measures or represents", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "feature_id": { + "description": "Unique identifier for this feature (e.g., 'consent_quality', 'carbon_score', 'coppa_certified')", + "type": "string" + }, + "methodology_url": { + "description": "URL to documentation explaining how this feature is calculated/measured", + "format": "uri", + "type": "string" + }, + "methodology_version": { + "description": "Version identifier for the methodology (for audit trails)", + "type": "string" + }, + "name": { + "description": "Human-readable name for the feature", + "type": "string" + }, + "range": { + "additionalProperties": false, + "description": "For quantitative features, the valid range of values", + "properties": { + "max": { + "description": "Maximum value", + "type": "number" + }, + "min": { + "description": "Minimum value", + "type": "number" + } + }, + "required": [ + "min", + "max" + ], + "type": "object" + }, + "type": { + "description": "The type of values this feature produces: binary (true/false), quantitative (numeric range), categorical (enumerated values)", + "enum": [ + "binary", + "quantitative", + "categorical" + ], + "type": "string" + } + }, + "required": [ + "feature_id", + "name", + "type", + "methodology_url" + ], + "title": "Property Feature Definition", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-feature.json b/schemas/cache/property/property-feature.json new file mode 100644 index 00000000..c2869ffe --- /dev/null +++ b/schemas/cache/property/property-feature.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "A discrete feature assessment for a property (e.g., from app store privacy labels)", + "properties": { + "feature_id": { + "description": "Identifier for the feature being assessed", + "type": "string" + }, + "source": { + "description": "Source of the feature data (e.g., app_store_privacy_label, tcf_string)", + "type": "string" + }, + "value": { + "description": "The feature value", + "type": "string" + } + }, + "required": [ + "feature_id", + "value" + ], + "title": "Property Feature", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-list-changed-webhook.json b/schemas/cache/property/property-list-changed-webhook.json new file mode 100644 index 00000000..eb9dc0a1 --- /dev/null +++ b/schemas/cache/property/property-list-changed-webhook.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Webhook notification sent when a property list's resolved properties change. Contains a summary only - recipients must call get_property_list to retrieve the updated properties. This keeps payloads small and avoids redundant data transfer.", + "properties": { + "cache_valid_until": { + "description": "When the consumer should refresh from the governance agent", + "format": "date-time", + "type": "string" + }, + "change_summary": { + "additionalProperties": false, + "description": "Summary of changes to the resolved list", + "properties": { + "properties_added": { + "description": "Number of properties added since last resolution", + "type": "integer" + }, + "properties_removed": { + "description": "Number of properties removed since last resolution", + "type": "integer" + }, + "total_properties": { + "description": "Total properties in the resolved list", + "type": "integer" + } + }, + "type": "object" + }, + "event": { + "const": "property_list_changed", + "description": "The event type", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "list_id": { + "description": "ID of the property list that changed", + "type": "string" + }, + "list_name": { + "description": "Name of the property list", + "type": "string" + }, + "resolved_at": { + "description": "When the list was re-resolved", + "format": "date-time", + "type": "string" + }, + "signature": { + "description": "Cryptographic signature of the webhook payload, signed with the agent's private key. Recipients MUST verify this signature.", + "type": "string" + } + }, + "required": [ + "event", + "list_id", + "resolved_at", + "signature" + ], + "title": "Property List Changed Webhook", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-list-filters.json b/schemas/cache/property/property-list-filters.json new file mode 100644 index 00000000..c39c1e62 --- /dev/null +++ b/schemas/cache/property/property-list-filters.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Filters that dynamically modify a property list when resolved", + "properties": { + "channels_any": { + "description": "Property must support ANY of the listed channels. Required.", + "items": { + "$ref": "../enums/channels.json" + }, + "type": "array" + }, + "countries_all": { + "description": "Property must have feature data for ALL listed countries (ISO codes). Required.", + "items": { + "pattern": "^[A-Z]{2}$", + "type": "string" + }, + "type": "array" + }, + "exclude_identifiers": { + "description": "Identifiers to always exclude from results", + "items": { + "$ref": "../core/identifier.json" + }, + "type": "array" + }, + "feature_requirements": { + "description": "Feature-based requirements. Property must pass ALL requirements (AND logic).", + "items": { + "$ref": "feature-requirement.json" + }, + "type": "array" + }, + "property_types": { + "description": "Filter to these property types", + "items": { + "$ref": "../enums/property-type.json" + }, + "type": "array" + } + }, + "required": [ + "countries_all", + "channels_any" + ], + "title": "Property List Filters", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/property-list.json b/schemas/cache/property/property-list.json new file mode 100644 index 00000000..17b1ba82 --- /dev/null +++ b/schemas/cache/property/property-list.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "A managed property list with optional filters for dynamic evaluation. Lists are resolved at setup time and cached by orchestrators/sellers for real-time use.", + "properties": { + "base_properties": { + "description": "Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database.", + "items": { + "$ref": "base-property-source.json" + }, + "type": "array" + }, + "brand_manifest": { + "$ref": "../core/brand-manifest.json", + "description": "Brand identity used to automatically apply appropriate rules" + }, + "cache_duration_hours": { + "default": 24, + "description": "Recommended cache duration for resolved list. Consumers should re-fetch after this period.", + "minimum": 1, + "type": "integer" + }, + "created_at": { + "description": "When the list was created", + "format": "date-time", + "type": "string" + }, + "description": { + "description": "Description of the list's purpose", + "type": "string" + }, + "filters": { + "$ref": "property-list-filters.json", + "description": "Dynamic filters applied when resolving the list" + }, + "list_id": { + "description": "Unique identifier for this property list", + "type": "string" + }, + "name": { + "description": "Human-readable name for the list", + "type": "string" + }, + "principal": { + "description": "Principal identity that owns this list", + "type": "string" + }, + "property_count": { + "description": "Number of properties in the resolved list (at time of last resolution)", + "type": "integer" + }, + "updated_at": { + "description": "When the list was last modified", + "format": "date-time", + "type": "string" + }, + "webhook_url": { + "description": "URL to receive notifications when the resolved list changes", + "format": "uri", + "type": "string" + } + }, + "required": [ + "list_id", + "name" + ], + "title": "Property List", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/update-property-list-request.json b/schemas/cache/property/update-property-list-request.json new file mode 100644 index 00000000..91ff96a0 --- /dev/null +++ b/schemas/cache/property/update-property-list-request.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Request parameters for updating an existing property list", + "properties": { + "base_properties": { + "description": "Complete replacement for the base properties list (not a patch). Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers).", + "items": { + "$ref": "base-property-source.json" + }, + "type": "array" + }, + "brand_manifest": { + "$ref": "../core/brand-manifest.json", + "description": "Update brand identity and requirements" + }, + "context": { + "$ref": "../core/context.json" + }, + "description": { + "description": "New description", + "type": "string" + }, + "ext": { + "$ref": "../core/ext.json" + }, + "filters": { + "$ref": "property-list-filters.json", + "description": "Complete replacement for the filters (not a patch)" + }, + "list_id": { + "description": "ID of the property list to update", + "type": "string" + }, + "name": { + "description": "New name for the list", + "type": "string" + }, + "webhook_url": { + "description": "Update the webhook URL for list change notifications (set to empty string to remove)", + "format": "uri", + "type": "string" + } + }, + "required": [ + "list_id" + ], + "title": "Update Property List Request", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/property/update-property-list-response.json b/schemas/cache/property/update-property-list-response.json new file mode 100644 index 00000000..3586c0c7 --- /dev/null +++ b/schemas/cache/property/update-property-list-response.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "Response payload for update_property_list task", + "properties": { + "ext": { + "$ref": "../core/ext.json" + }, + "list": { + "$ref": "property-list.json", + "description": "The updated property list" + } + }, + "required": [ + "list" + ], + "title": "Update Property List Response", + "type": "object" +} \ No newline at end of file diff --git a/schemas/cache/protocols/adcp-extension.json b/schemas/cache/protocols/adcp-extension.json index a5dbab16..47f1dabb 100644 --- a/schemas/cache/protocols/adcp-extension.json +++ b/schemas/cache/protocols/adcp-extension.json @@ -1,13 +1,23 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": true, - "description": "Extension metadata for agent cards (MCP and A2A) declaring AdCP version and supported protocol domains", + "description": "Parameters for declaring AdCP support in agent discovery. For A2A, use in extensions[].params. For MCP, use in _meta['adcontextprotocol.org'].", "properties": { "adcp_version": { - "description": "Semantic version of the AdCP specification this agent implements (e.g., '2.4.0')", + "description": "Semantic version of the AdCP specification this agent implements (e.g., '2.5.0'). Extension schemas are versioned along with the AdCP spec.", "pattern": "^\\d+\\.\\d+\\.\\d+$", "type": "string" }, + "extensions_supported": { + "description": "Typed extensions this agent supports. Each extension has a formal schema in /schemas/extensions/. Extension version is determined by adcp_version.", + "items": { + "description": "Extension namespace (e.g., 'sustainability'). Must be lowercase alphanumeric with underscores.", + "pattern": "^[a-z][a-z0-9_]*$", + "type": "string" + }, + "type": "array", + "uniqueItems": true + }, "protocols_supported": { "description": "AdCP protocol domains supported by this agent. At least one must be specified.", "items": { @@ -27,6 +37,6 @@ "adcp_version", "protocols_supported" ], - "title": "AdCP Agent Card Extension", + "title": "AdCP Agent Card Extension Params", "type": "object" } \ No newline at end of file diff --git a/scripts/generate_ergonomic_coercion.py b/scripts/generate_ergonomic_coercion.py index d39483d4..52d6bd6e 100644 --- a/scripts/generate_ergonomic_coercion.py +++ b/scripts/generate_ergonomic_coercion.py @@ -82,6 +82,7 @@ def get_base_type(annotation: Any) -> Any: # Handle Union types (including Optional which is Union[X, None]) # Check if it's a union by looking at origin import types + if origin is types.UnionType: args = get_args(annotation) # Filter out None type @@ -137,50 +138,61 @@ def analyze_model(model_class) -> list[dict]: # Check for enum field if isinstance(base_type, type) and issubclass(base_type, Enum): - coercions.append({ - "field": field_name, - "type": "enum", - "target_class": base_type, - }) + coercions.append( + { + "field": field_name, + "type": "enum", + "target_class": base_type, + } + ) continue # Check for list[Enum] - is_enum_list, enum_type = is_list_of(annotation, lambda t: isinstance(t, type) and issubclass(t, Enum)) + is_enum_list, enum_type = is_list_of( + annotation, lambda t: isinstance(t, type) and issubclass(t, Enum) + ) if is_enum_list: - coercions.append({ - "field": field_name, - "type": "enum_list", - "target_class": enum_type, - }) + coercions.append( + { + "field": field_name, + "type": "enum_list", + "target_class": enum_type, + } + ) continue # Check for ContextObject if base_type is ContextObject: - coercions.append({ - "field": field_name, - "type": "context", - }) + coercions.append( + { + "field": field_name, + "type": "context", + } + ) continue # Check for ExtensionObject if base_type is ExtensionObject: - coercions.append({ - "field": field_name, - "type": "ext", - }) + coercions.append( + { + "field": field_name, + "type": "ext", + } + ) continue # Check for list[BaseModel] - for subclass variance is_model_list, model_type = is_list_of( - annotation, - lambda t: isinstance(t, type) and issubclass(t, BaseModel) + annotation, lambda t: isinstance(t, type) and issubclass(t, BaseModel) ) if is_model_list and model_type.__name__ in SUBCLASS_LIST_TYPES: - coercions.append({ - "field": field_name, - "type": "subclass_list", - "target_class": model_type, - }) + coercions.append( + { + "field": field_name, + "type": "subclass_list", + "target_class": model_type, + } + ) continue return coercions @@ -284,103 +296,107 @@ def generate_code() -> str: # Build the module lines = [ - '# AUTO-GENERATED by scripts/generate_ergonomic_coercion.py', - '# Do not edit manually - changes will be overwritten on next type generation.', - '# To regenerate: python scripts/generate_types.py', + "# AUTO-GENERATED by scripts/generate_ergonomic_coercion.py", + "# Do not edit manually - changes will be overwritten on next type generation.", + "# To regenerate: python scripts/generate_types.py", '"""Apply type coercion to generated types for better ergonomics.', - '', - 'This module patches the generated types to accept more flexible input types', - 'while maintaining type safety. It uses Pydantic\'s model_rebuild() to add', - 'BeforeValidator annotations to fields.', - '', - 'Why import-time patching?', - ' We apply coercion at module load time rather than lazily because:', - ' 1. Pydantic validation runs during __init__, before any lazy access', - ' 2. model_rebuild() is the standard Pydantic pattern for post-hoc changes', - ' 3. The cost is minimal (~10-20ms for all types, once at import)', - ' 4. After import, there is zero runtime overhead', - ' 5. This approach maintains full type checker compatibility', - '', - 'Coercion rules applied:', + "", + "This module patches the generated types to accept more flexible input types", + "while maintaining type safety. It uses Pydantic's model_rebuild() to add", + "BeforeValidator annotations to fields.", + "", + "Why import-time patching?", + " We apply coercion at module load time rather than lazily because:", + " 1. Pydantic validation runs during __init__, before any lazy access", + " 2. model_rebuild() is the standard Pydantic pattern for post-hoc changes", + " 3. The cost is minimal (~10-20ms for all types, once at import)", + " 4. After import, there is zero runtime overhead", + " 5. This approach maintains full type checker compatibility", + "", + "Coercion rules applied:", '1. Enum fields accept string values (e.g., "video" for FormatCategory.video)', '2. List[Enum] fields accept list of strings (e.g., ["image", "video"])', - '3. ContextObject fields accept dict values', - '4. ExtensionObject fields accept dict values', - '5. FieldModel (enum) lists accept string lists', - '', - 'Note: List variance issues (list[Subclass] not assignable to list[BaseClass])', - 'are a fundamental Python typing limitation. Users extending library types', - 'should use Sequence[T] in their own code or cast() for type checker appeasement.', + "3. ContextObject fields accept dict values", + "4. ExtensionObject fields accept dict values", + "5. FieldModel (enum) lists accept string lists", + "", + "Note: List variance issues (list[Subclass] not assignable to list[BaseClass])", + "are a fundamental Python typing limitation. Users extending library types", + "should use Sequence[T] in their own code or cast() for type checker appeasement.", '"""', - '', - 'from __future__ import annotations', - '', - 'from typing import Annotated, Any', - '', - 'from pydantic import BeforeValidator', - '', - 'from adcp.types.coercion import (', - ' coerce_subclass_list,', - ' coerce_to_enum,', - ' coerce_to_enum_list,', - ' coerce_to_model,', - ')', - '', + "", + "from __future__ import annotations", + "", + "from typing import Annotated, Any", + "", + "from pydantic import BeforeValidator", + "", + "from adcp.types.coercion import (", + " coerce_subclass_list,", + " coerce_to_enum,", + " coerce_to_enum_list,", + " coerce_to_model,", + ")", + "", ] # Add core imports for name, path in core_imports: - lines.append(f'from adcp.types.generated_poc.{path} import {name}') + lines.append(f"from adcp.types.generated_poc.{path} import {name}") # Add enum imports for name, path in enum_imports: - lines.append(f'from adcp.types.generated_poc.{path} import {name}') + lines.append(f"from adcp.types.generated_poc.{path} import {name}") # Add request type imports - lines.append('from adcp.types.generated_poc.media_buy.create_media_buy_request import (') - lines.append(' CreateMediaBuyRequest,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.get_products_request import GetProductsRequest') - lines.append('from adcp.types.generated_poc.media_buy.list_creative_formats_request import (') - lines.append(' ListCreativeFormatsRequest,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.list_creatives_request import (') - lines.append(' FieldModel,') - lines.append(' ListCreativesRequest,') - lines.append(' Sort,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.package_request import PackageRequest') - lines.append('from adcp.types.generated_poc.media_buy.update_media_buy_request import (') - lines.append(' Packages,') - lines.append(' Packages1,') - lines.append(')') + lines.append("from adcp.types.generated_poc.media_buy.create_media_buy_request import (") + lines.append(" CreateMediaBuyRequest,") + lines.append(")") + lines.append( + "from adcp.types.generated_poc.media_buy.get_products_request import GetProductsRequest" + ) + lines.append("from adcp.types.generated_poc.media_buy.list_creative_formats_request import (") + lines.append(" ListCreativeFormatsRequest,") + lines.append(")") + lines.append("from adcp.types.generated_poc.media_buy.list_creatives_request import (") + lines.append(" FieldModel,") + lines.append(" ListCreativesRequest,") + lines.append(" Sort,") + lines.append(")") + lines.append("from adcp.types.generated_poc.media_buy.package_request import PackageRequest") + lines.append("from adcp.types.generated_poc.media_buy.update_media_buy_request import (") + lines.append(" Packages,") + lines.append(" Packages1,") + lines.append(")") # Add response type imports - lines.append('from adcp.types.generated_poc.media_buy.create_media_buy_response import (') - lines.append(' CreateMediaBuyResponse1,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.get_media_buy_delivery_response import (') - lines.append(' GetMediaBuyDeliveryResponse,') - lines.append(' MediaBuyDelivery,') - lines.append(' NotificationType,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.get_products_response import GetProductsResponse') - lines.append('from adcp.types.generated_poc.media_buy.list_creative_formats_response import (') - lines.append(' CreativeAgent,') - lines.append(' ListCreativeFormatsResponse,') - lines.append(')') - lines.append('from adcp.types.generated_poc.media_buy.list_creatives_response import (') - lines.append(' Creative,') - lines.append(' ListCreativesResponse,') - lines.append(')') - - lines.append('') - lines.append('') - lines.append('def _apply_coercion() -> None:') + lines.append("from adcp.types.generated_poc.media_buy.create_media_buy_response import (") + lines.append(" CreateMediaBuyResponse1,") + lines.append(")") + lines.append("from adcp.types.generated_poc.media_buy.get_media_buy_delivery_response import (") + lines.append(" GetMediaBuyDeliveryResponse,") + lines.append(" MediaBuyDelivery,") + lines.append(" NotificationType,") + lines.append(")") + lines.append( + "from adcp.types.generated_poc.media_buy.get_products_response import GetProductsResponse" + ) + lines.append("from adcp.types.generated_poc.media_buy.list_creative_formats_response import (") + lines.append(" CreativeAgent,") + lines.append(" ListCreativeFormatsResponse,") + lines.append(")") + lines.append("from adcp.types.generated_poc.media_buy.list_creatives_response import (") + lines.append(" Creative,") + lines.append(" ListCreativesResponse,") + lines.append(")") + + lines.append("") + lines.append("") + lines.append("def _apply_coercion() -> None:") lines.append(' """Apply coercion validators to generated types.') - lines.append('') - lines.append(' This function modifies the generated types in-place to accept') - lines.append(' more flexible input types.') + lines.append("") + lines.append(" This function modifies the generated types in-place to accept") + lines.append(" more flexible input types.") lines.append(' """') # Generate coercion code for each type @@ -415,91 +431,101 @@ def generate_code() -> str: if c["type"] == "enum": field_comments.append(f'{c["field"]}: {c["target_class"].__name__} | str | None') elif c["type"] == "enum_list": - field_comments.append(f'{c["field"]}: list[{c["target_class"].__name__} | str] | None') + field_comments.append( + f'{c["field"]}: list[{c["target_class"].__name__} | str] | None' + ) elif c["type"] == "context": field_comments.append(f'{c["field"]}: ContextObject | dict | None') elif c["type"] == "ext": field_comments.append(f'{c["field"]}: ExtensionObject | dict | None') elif c["type"] == "subclass_list": - field_comments.append(f'{c["field"]}: list[{c["target_class"].__name__}] (accepts subclass instances)') + field_comments.append( + f'{c["field"]}: list[{c["target_class"].__name__}] (accepts subclass instances)' + ) - lines.append(f' # Apply coercion to {type_name}') + lines.append(f" # Apply coercion to {type_name}") for comment in field_comments: - lines.append(f' # - {comment}') + lines.append(f" # - {comment}") # Generate the actual coercion code for c in coercions: field = c["field"] if c["type"] == "enum": target = c["target_class"].__name__ - lines.append(' _patch_field_annotation(') - lines.append(f' {type_name},') + lines.append(" _patch_field_annotation(") + lines.append(f" {type_name},") lines.append(f' "{field}",') - lines.append(f' Annotated[{target} | None, BeforeValidator(coerce_to_enum({target}))],') - lines.append(' )') + lines.append( + f" Annotated[{target} | None, BeforeValidator(coerce_to_enum({target}))]," + ) + lines.append(" )") elif c["type"] == "enum_list": target = c["target_class"].__name__ - lines.append(' _patch_field_annotation(') - lines.append(f' {type_name},') + lines.append(" _patch_field_annotation(") + lines.append(f" {type_name},") lines.append(f' "{field}",') - lines.append(' Annotated[') - lines.append(f' list[{target}] | None,') - lines.append(f' BeforeValidator(coerce_to_enum_list({target})),') - lines.append(' ],') - lines.append(' )') + lines.append(" Annotated[") + lines.append(f" list[{target}] | None,") + lines.append(f" BeforeValidator(coerce_to_enum_list({target})),") + lines.append(" ],") + lines.append(" )") elif c["type"] == "context": - lines.append(' _patch_field_annotation(') - lines.append(f' {type_name},') + lines.append(" _patch_field_annotation(") + lines.append(f" {type_name},") lines.append(f' "{field}",') - lines.append(' Annotated[ContextObject | None, BeforeValidator(coerce_to_model(ContextObject))],') - lines.append(' )') + lines.append( + " Annotated[ContextObject | None, BeforeValidator(coerce_to_model(ContextObject))]," + ) + lines.append(" )") elif c["type"] == "ext": - lines.append(' _patch_field_annotation(') - lines.append(f' {type_name},') + lines.append(" _patch_field_annotation(") + lines.append(f" {type_name},") lines.append(f' "{field}",') - lines.append(' Annotated[ExtensionObject | None, BeforeValidator(coerce_to_model(ExtensionObject))],') - lines.append(' )') + lines.append( + " Annotated[ExtensionObject | None, BeforeValidator(coerce_to_model(ExtensionObject))]," + ) + lines.append(" )") elif c["type"] == "subclass_list": target = c["target_class"].__name__ # Check if the field is required (no | None) field_info = cls.model_fields[field] is_optional = "None" in str(field_info.annotation) - type_str = f'list[{target}] | None' if is_optional else f'list[{target}]' - lines.append(' _patch_field_annotation(') - lines.append(f' {type_name},') + type_str = f"list[{target}] | None" if is_optional else f"list[{target}]" + lines.append(" _patch_field_annotation(") + lines.append(f" {type_name},") lines.append(f' "{field}",') - lines.append(' Annotated[') - lines.append(f' {type_str},') - lines.append(f' BeforeValidator(coerce_subclass_list({target})),') - lines.append(' ],') - lines.append(' )') + lines.append(" Annotated[") + lines.append(f" {type_str},") + lines.append(f" BeforeValidator(coerce_subclass_list({target})),") + lines.append(" ],") + lines.append(" )") - lines.append(f' {type_name}.model_rebuild(force=True)') - lines.append('') + lines.append(f" {type_name}.model_rebuild(force=True)") + lines.append("") # Handle Packages and Packages1 together if they have same coercions # (they're already handled in the loop above) # Add helper function - lines.append('') - lines.append('def _patch_field_annotation(') - lines.append(' model: type,') - lines.append(' field_name: str,') - lines.append(' new_annotation: Any,') - lines.append(') -> None:') + lines.append("") + lines.append("def _patch_field_annotation(") + lines.append(" model: type,") + lines.append(" field_name: str,") + lines.append(" new_annotation: Any,") + lines.append(") -> None:") lines.append(' """Patch a field annotation on a Pydantic model.') - lines.append('') - lines.append(' This modifies the model\'s __annotations__ dict to add') - lines.append(' BeforeValidator coercion.') + lines.append("") + lines.append(" This modifies the model's __annotations__ dict to add") + lines.append(" BeforeValidator coercion.") lines.append(' """') - lines.append(' model.__annotations__[field_name] = new_annotation') - lines.append('') - lines.append('') - lines.append('# Apply coercion when module is imported') - lines.append('_apply_coercion()') - lines.append('') - - return '\n'.join(lines) + lines.append(" model.__annotations__[field_name] = new_annotation") + lines.append("") + lines.append("") + lines.append("# Apply coercion when module is imported") + lines.append("_apply_coercion()") + lines.append("") + + return "\n".join(lines) def main(): diff --git a/scripts/post_generate_fixes.py b/scripts/post_generate_fixes.py index 40c48281..bc6489ec 100644 --- a/scripts/post_generate_fixes.py +++ b/scripts/post_generate_fixes.py @@ -219,7 +219,7 @@ def add_deprecated_field_metadata(): continue # Find the Field( after this field definition - field_section = content[field_start:field_start + 500] + field_section = content[field_start : field_start + 500] if "deprecated=True" in field_section.split("] = ")[0]: continue # Already fixed @@ -232,9 +232,13 @@ def add_deprecated_field_metadata(): # Insert deprecated=True after Field( insert_pos = match.end() # Check what comes after - if it's description=, add before it - after_match = content[insert_pos:insert_pos + 50] + after_match = content[insert_pos : insert_pos + 50] if after_match.strip().startswith("description="): - new_content = content[:insert_pos] + "deprecated=True,\n " + content[insert_pos:] + new_content = ( + content[:insert_pos] + + "deprecated=True,\n " + + content[insert_pos:] + ) else: new_content = content[:insert_pos] + "deprecated=True, " + content[insert_pos:] diff --git a/src/adcp/protocols/mcp.py b/src/adcp/protocols/mcp.py index c07f1e7a..ac6c16b2 100644 --- a/src/adcp/protocols/mcp.py +++ b/src/adcp/protocols/mcp.py @@ -136,7 +136,9 @@ def _log_cleanup_error(self, exc: BaseException, context: str) -> None: and ("cancel scope" in exc_str or "async context" in exc_str) ) or ( # HTTP errors during cleanup (if httpx is available) - HTTPX_AVAILABLE and HTTPStatusError is not None and isinstance(exc, HTTPStatusError) + HTTPX_AVAILABLE + and HTTPStatusError is not None + and isinstance(exc, HTTPStatusError) ) if is_known_cleanup_error: diff --git a/src/adcp/types/_ergonomic.py b/src/adcp/types/_ergonomic.py index f828abab..22a97d63 100644 --- a/src/adcp/types/_ergonomic.py +++ b/src/adcp/types/_ergonomic.py @@ -39,8 +39,6 @@ coerce_to_enum_list, coerce_to_model, ) - -# Import types that need coercion from adcp.types.generated_poc.core.context import ContextObject from adcp.types.generated_poc.core.creative_asset import CreativeAsset from adcp.types.generated_poc.core.creative_assignment import CreativeAssignment @@ -57,8 +55,6 @@ from adcp.types.generated_poc.media_buy.create_media_buy_request import ( CreateMediaBuyRequest, ) - -# Response types from adcp.types.generated_poc.media_buy.create_media_buy_response import ( CreateMediaBuyResponse1, ) diff --git a/src/adcp/types/_generated.py b/src/adcp/types/_generated.py index 62b34202..b0e897ad 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: 2026-01-08 19:25:24 UTC +Generation date: 2026-01-14 17:08:13 UTC """ # ruff: noqa: E501, I001 @@ -26,6 +26,7 @@ AuthorizedSalesAgents1, AuthorizedSalesAgents2, Contact, + PropertyFeature, Tags, ) from adcp.types.generated_poc.core.activation_key import ( @@ -91,6 +92,7 @@ ) from adcp.types.generated_poc.core.format_id import FormatId from adcp.types.generated_poc.core.frequency_cap import FrequencyCap +from adcp.types.generated_poc.core.identifier import Identifier from adcp.types.generated_poc.core.mcp_webhook_payload import McpWebhookPayload from adcp.types.generated_poc.core.measurement import Measurement from adcp.types.generated_poc.core.media_buy import MediaBuy @@ -120,8 +122,9 @@ PromotedOfferings, ) from adcp.types.generated_poc.core.promoted_products import PromotedProducts -from adcp.types.generated_poc.core.property import Identifier, Property +from adcp.types.generated_poc.core.property import Property from adcp.types.generated_poc.core.property_id import PropertyId +from adcp.types.generated_poc.core.property_list_ref import PropertyListReference from adcp.types.generated_poc.core.property_tag import PropertyTag from adcp.types.generated_poc.core.protocol_envelope import ProtocolEnvelope from adcp.types.generated_poc.core.publisher_property_selector import ( @@ -219,6 +222,7 @@ from adcp.types.generated_poc.enums.vast_version import VastVersion from adcp.types.generated_poc.enums.webhook_response_type import WebhookResponseType from adcp.types.generated_poc.enums.webhook_security_method import WebhookSecurityMethod +from adcp.types.generated_poc.extensions.extension_meta import AdcpExtensionFileSchema from adcp.types.generated_poc.media_buy.build_creative_request import BuildCreativeRequest from adcp.types.generated_poc.media_buy.build_creative_response import ( BuildCreativeResponse, @@ -364,8 +368,53 @@ from adcp.types.generated_poc.pricing_options.flat_rate_option import FlatRatePricingOption from adcp.types.generated_poc.pricing_options.vcpm_auction_option import VcpmAuctionPricingOption from adcp.types.generated_poc.pricing_options.vcpm_fixed_option import VcpmFixedRatePricingOption +from adcp.types.generated_poc.property.base_property_source import ( + BasePropertySource, + BasePropertySource1, + BasePropertySource2, + BasePropertySource3, +) +from adcp.types.generated_poc.property.create_property_list_request import CreatePropertyListRequest +from adcp.types.generated_poc.property.create_property_list_response import ( + CreatePropertyListResponse, +) +from adcp.types.generated_poc.property.delete_property_list_request import DeletePropertyListRequest +from adcp.types.generated_poc.property.delete_property_list_response import ( + DeletePropertyListResponse, +) +from adcp.types.generated_poc.property.feature_requirement import FeatureRequirement, IfNotCovered +from adcp.types.generated_poc.property.get_property_list_request import GetPropertyListRequest +from adcp.types.generated_poc.property.get_property_list_response import GetPropertyListResponse +from adcp.types.generated_poc.property.list_property_features_request import ( + ListPropertyFeaturesRequest, +) +from adcp.types.generated_poc.property.list_property_features_response import ( + ListPropertyFeaturesResponse, +) +from adcp.types.generated_poc.property.list_property_lists_request import ListPropertyListsRequest +from adcp.types.generated_poc.property.list_property_lists_response import ListPropertyListsResponse +from adcp.types.generated_poc.property.property_error import Code, PropertyError +from adcp.types.generated_poc.property.property_feature_definition import ( + Coverage, + PropertyFeatureDefinition, + Range, +) +from adcp.types.generated_poc.property.property_list import PropertyList +from adcp.types.generated_poc.property.property_list_changed_webhook import ( + ChangeSummary, + PropertyListChangedWebhook, +) +from adcp.types.generated_poc.property.property_list_filters import ( + CountriesAllItem, + PropertyListFilters, +) +from adcp.types.generated_poc.property.update_property_list_request import UpdatePropertyListRequest +from adcp.types.generated_poc.property.update_property_list_response import ( + UpdatePropertyListResponse, +) from adcp.types.generated_poc.protocols.adcp_extension import ( - AdcpAgentCardExtension, + AdcpAgentCardExtensionParams, + ExtensionsSupportedItem, ProtocolsSupportedEnum, ) from adcp.types.generated_poc.signals.activate_signal_request import ActivateSignalRequest @@ -396,9 +445,10 @@ "ActivationKey", "ActivationKey1", "ActivationKey2", - "AdcpAgentCardExtension", + "AdcpAgentCardExtensionParams", "AdcpAsyncResponseData", "AdcpDomain", + "AdcpExtensionFileSchema", "AdvertisingChannels", "AggregatedTotals", "Asset", @@ -423,6 +473,10 @@ "AuthorizedSalesAgents1", "AuthorizedSalesAgents2", "AvailableMetric", + "BasePropertySource", + "BasePropertySource1", + "BasePropertySource2", + "BasePropertySource3", "BrandManifest", "BrandManifestReference", "BudgetRange", @@ -432,12 +486,16 @@ "BuildCreativeResponse1", "BuildCreativeResponse2", "ByPackageItem", + "ChangeSummary", "Channels", "CoBrandingRequirement", + "Code", "Colors", "Contact", "ContextObject", + "CountriesAllItem", "Country", + "Coverage", "CpcPricingOption", "CpcvPricingOption", "CpmAuctionPricingOption", @@ -451,6 +509,8 @@ "CreateMediaBuyResponse2", "CreateMediaBuySubmitted", "CreateMediaBuyWorking", + "CreatePropertyListRequest", + "CreatePropertyListResponse", "Creative", "CreativeAction", "CreativeAgent", @@ -469,6 +529,8 @@ "DaastTrackingEvent", "DaastVersion", "DailyBreakdownItem", + "DeletePropertyListRequest", + "DeletePropertyListResponse", "DeliverTo", "DeliveryMeasurement", "DeliveryMetrics", @@ -488,6 +550,8 @@ "Embedding", "Error", "ExtensionObject", + "ExtensionsSupportedItem", + "FeatureRequirement", "FeedFormat", "FeedbackSource", "FieldModel", @@ -509,12 +573,15 @@ "GetProductsResponse", "GetProductsSubmitted", "GetProductsWorking", + "GetPropertyListRequest", + "GetPropertyListResponse", "GetSignalsRequest", "GetSignalsResponse", "HistoryEntryType", "HtmlAsset", "HttpMethod", "Identifier", + "IfNotCovered", "ImageAsset", "Input", "Input2", @@ -530,6 +597,10 @@ "ListCreativeFormatsResponseCreativeAgent", "ListCreativesRequest", "ListCreativesResponse", + "ListPropertyFeaturesRequest", + "ListPropertyFeaturesResponse", + "ListPropertyListsRequest", + "ListPropertyListsResponse", "Logo", "MarkdownFlavor", "McpWebhookPayload", @@ -580,8 +651,15 @@ "PromotedOfferings", "PromotedProducts", "Property", + "PropertyError", + "PropertyFeature", + "PropertyFeatureDefinition", "PropertyId", "PropertyIdentifierTypes", + "PropertyList", + "PropertyListChangedWebhook", + "PropertyListFilters", + "PropertyListReference", "PropertyTag", "PropertyType", "ProtocolEnvelope", @@ -602,6 +680,7 @@ "PushNotificationConfig", "QuartileData", "QuerySummary", + "Range", "Reason", "Renders", "Renders1", @@ -654,6 +733,8 @@ "UpdateMediaBuyResponse2", "UpdateMediaBuySubmitted", "UpdateMediaBuyWorking", + "UpdatePropertyListRequest", + "UpdatePropertyListResponse", "UrlAsset", "UrlAssetType", "ValidationMode", diff --git a/src/adcp/types/generated_poc/adagents.py b/src/adcp/types/generated_poc/adagents.py index e5dfea04..21dc5abf 100644 --- a/src/adcp/types/generated_poc/adagents.py +++ b/src/adcp/types/generated_poc/adagents.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: adagents.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -14,39 +14,39 @@ class AuthorizedSalesAgents1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) field_schema: Annotated[ str | None, - Field(alias='$schema', description='JSON Schema identifier for this adagents.json file'), + Field(alias="$schema", description="JSON Schema identifier for this adagents.json file"), ] = None authoritative_location: Annotated[ AnyUrl, Field( - description='HTTPS URL of the authoritative adagents.json file. When present, this file is a reference and the authoritative location contains the actual agent authorization data.' + description="HTTPS URL of the authoritative adagents.json file. When present, this file is a reference and the authoritative location contains the actual agent authorization data." ), ] last_updated: Annotated[ AwareDatetime | None, - Field(description='ISO 8601 timestamp indicating when this reference was last updated'), + Field(description="ISO 8601 timestamp indicating when this reference was last updated"), ] = None class Contact(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) domain: Annotated[ str | None, Field( - description='Primary domain of the entity managing this file', - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + description="Primary domain of the entity managing this file", + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] = None email: Annotated[ EmailStr | None, Field( - description='Contact email for questions or issues with this authorization file', + description="Contact email for questions or issues with this authorization file", max_length=255, min_length=1, ), @@ -62,7 +62,7 @@ class Contact(AdCPBaseModel): seller_id: Annotated[ str | None, Field( - description='Seller ID from IAB Tech Lab sellers.json (if applicable)', + description="Seller ID from IAB Tech Lab sellers.json (if applicable)", max_length=255, min_length=1, ), @@ -70,33 +70,59 @@ class Contact(AdCPBaseModel): tag_id: Annotated[ str | None, Field( - description='TAG Certified Against Fraud ID for verification (if applicable)', + description="TAG Certified Against Fraud ID for verification (if applicable)", max_length=100, min_length=1, ), ] = None +class PropertyFeature(AdCPBaseModel): + model_config = ConfigDict( + extra="allow", + ) + features: Annotated[ + list[str], + Field( + description="Feature IDs this agent provides (e.g., 'carbon_score', 'tag_certified_against_fraud'). Use list_property_features on the agent for full definitions.", + min_length=1, + ), + ] + name: Annotated[ + str, + Field( + description="Human-readable name of the vendor/agent (e.g., 'Scope3', 'TAG', 'OneTrust')" + ), + ] + publisher_id: Annotated[ + str | None, Field(description="Optional publisher identifier at this agent (for lookup)") + ] = None + url: Annotated[ + AnyUrl, + Field(description="The agent's API endpoint URL (must implement get_property_features)"), + ] + + class Tags(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - description: Annotated[str, Field(description='Description of what this tag represents')] - name: Annotated[str, Field(description='Human-readable name for this tag')] + description: Annotated[str, Field(description="Description of what this tag represents")] + name: Annotated[str, Field(description="Human-readable name for this tag")] class AuthorizedAgents(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) authorization_type: Annotated[ - Literal['property_ids'], - Field(description='Discriminator indicating authorization by specific property IDs'), + Literal["property_ids"], + Field(description="Discriminator indicating authorization by specific property IDs"), ] authorized_for: Annotated[ str, Field( - description='Human-readable description of what this agent is authorized to sell', + description="Human-readable description of what this agent is authorized to sell", max_length=500, min_length=1, ), @@ -104,7 +130,7 @@ class AuthorizedAgents(AdCPBaseModel): property_ids: Annotated[ list[property_id.PropertyId], Field( - description='Property IDs this agent is authorized for. Resolved against the top-level properties array in this file', + description="Property IDs this agent is authorized for. Resolved against the top-level properties array in this file", min_length=1, ), ] @@ -113,16 +139,16 @@ class AuthorizedAgents(AdCPBaseModel): class AuthorizedAgents1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) authorization_type: Annotated[ - Literal['property_tags'], - Field(description='Discriminator indicating authorization by property tags'), + Literal["property_tags"], + Field(description="Discriminator indicating authorization by property tags"), ] authorized_for: Annotated[ str, Field( - description='Human-readable description of what this agent is authorized to sell', + description="Human-readable description of what this agent is authorized to sell", max_length=500, min_length=1, ), @@ -130,7 +156,7 @@ class AuthorizedAgents1(AdCPBaseModel): property_tags: Annotated[ list[property_tag.PropertyTag], Field( - description='Tags identifying which properties this agent is authorized for. Resolved against the top-level properties array in this file using tag matching', + description="Tags identifying which properties this agent is authorized for. Resolved against the top-level properties array in this file using tag matching", min_length=1, ), ] @@ -139,18 +165,18 @@ class AuthorizedAgents1(AdCPBaseModel): class AuthorizedAgents3(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) authorization_type: Annotated[ - Literal['publisher_properties'], + Literal["publisher_properties"], Field( - description='Discriminator indicating authorization for properties from other publisher domains' + description="Discriminator indicating authorization for properties from other publisher domains" ), ] authorized_for: Annotated[ str, Field( - description='Human-readable description of what this agent is authorized to sell', + description="Human-readable description of what this agent is authorized to sell", max_length=500, min_length=1, ), @@ -158,7 +184,7 @@ class AuthorizedAgents3(AdCPBaseModel): publisher_properties: Annotated[ list[publisher_property_selector.PublisherPropertySelector], Field( - description='Properties from other publisher domains this agent is authorized for. Each entry specifies a publisher domain and which of their properties this agent can sell', + description="Properties from other publisher domains this agent is authorized for. Each entry specifies a publisher domain and which of their properties this agent can sell", min_length=1, ), ] @@ -167,16 +193,16 @@ class AuthorizedAgents3(AdCPBaseModel): class AuthorizedAgents2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) authorization_type: Annotated[ - Literal['inline_properties'], - Field(description='Discriminator indicating authorization by inline property definitions'), + Literal["inline_properties"], + Field(description="Discriminator indicating authorization by inline property definitions"), ] authorized_for: Annotated[ str, Field( - description='Human-readable description of what this agent is authorized to sell', + description="Human-readable description of what this agent is authorized to sell", max_length=500, min_length=1, ), @@ -184,7 +210,7 @@ class AuthorizedAgents2(AdCPBaseModel): properties: Annotated[ list[property.Property], Field( - description='Specific properties this agent is authorized for (alternative to property_ids/property_tags)', + description="Specific properties this agent is authorized for (alternative to property_ids/property_tags)", min_length=1, ), ] @@ -193,40 +219,46 @@ class AuthorizedAgents2(AdCPBaseModel): class AuthorizedSalesAgents2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) field_schema: Annotated[ str | None, - Field(alias='$schema', description='JSON Schema identifier for this adagents.json file'), + Field(alias="$schema", description="JSON Schema identifier for this adagents.json file"), ] = None authorized_agents: Annotated[ list[AuthorizedAgents | AuthorizedAgents1 | AuthorizedAgents2 | AuthorizedAgents3], Field( - description='Array of sales agents authorized to sell inventory for properties in this file', + description="Array of sales agents authorized to sell inventory for properties in this file", min_length=1, ), ] contact: Annotated[ Contact | None, Field( - description='Contact information for the entity managing this adagents.json file (may be publisher or third-party operator)' + description="Contact information for the entity managing this adagents.json file (may be publisher or third-party operator)" ), ] = None last_updated: Annotated[ AwareDatetime | None, - Field(description='ISO 8601 timestamp indicating when this file was last updated'), + Field(description="ISO 8601 timestamp indicating when this file was last updated"), ] = None properties: Annotated[ list[property.Property] | None, Field( - description='Array of all properties covered by this adagents.json file. Defines the canonical property list that authorized agents reference.', + description="Array of all properties covered by this adagents.json file. Defines the canonical property list that authorized agents reference.", min_length=1, ), ] = None + property_features: Annotated[ + list[PropertyFeature] | None, + Field( + description="[AdCP 3.0] Optional list of agents that provide property feature data (certifications, scores, compliance status). Used for discovery - actual data comes from querying the agent's get_property_features task." + ), + ] = None tags: Annotated[ dict[str, Tags] | None, Field( - description='Metadata for each tag referenced by properties. Provides human-readable context for property tag values.' + description="Metadata for each tag referenced by properties. Provides human-readable context for property tag values." ), ] = None @@ -235,173 +267,231 @@ class AuthorizedSalesAgents(RootModel[AuthorizedSalesAgents1 | AuthorizedSalesAg root: Annotated[ AuthorizedSalesAgents1 | AuthorizedSalesAgents2, Field( - description='Declaration of authorized sales agents for advertising inventory. Hosted at /.well-known/adagents.json on publisher domains. Can either contain the full structure inline or reference an authoritative URL.', + description="Declaration of authorized sales agents for advertising inventory. Hosted at /.well-known/adagents.json on publisher domains. Can either contain the full structure inline or reference an authoritative URL.", examples=[ { - '$schema': '/schemas/2.6.0/adagents.json', - 'authoritative_location': 'https://cdn.example.com/adagents/v2/adagents.json', - 'last_updated': '2025-01-15T10:00:00Z', + "$schema": "/schemas/2.6.0/adagents.json", + "authoritative_location": "https://cdn.example.com/adagents/v2/adagents.json", + "last_updated": "2025-01-15T10:00:00Z", }, { - '$schema': '/schemas/2.6.0/adagents.json', - 'authorized_agents': [ + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ { - 'authorization_type': 'property_tags', - 'authorized_for': 'Official sales agent', - 'property_tags': ['all'], - 'url': 'https://agent.example.com', + "authorization_type": "property_tags", + "authorized_for": "Official sales agent", + "property_tags": ["all"], + "url": "https://agent.example.com", } ], - 'last_updated': '2025-01-10T12:00:00Z', - 'properties': [ + "last_updated": "2025-01-10T12:00:00Z", + "properties": [ { - 'identifiers': [{'type': 'domain', 'value': 'example.com'}], - 'name': 'Example Site', - 'property_type': 'website', - 'publisher_domain': 'example.com', + "identifiers": [{"type": "domain", "value": "example.com"}], + "name": "Example Site", + "property_type": "website", + "publisher_domain": "example.com", } ], - 'tags': { - 'all': { - 'description': 'All properties in this file', - 'name': 'All Properties', + "tags": { + "all": { + "description": "All properties in this file", + "name": "All Properties", } }, }, { - '$schema': '/schemas/2.6.0/adagents.json', - 'authorized_agents': [ + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ { - 'authorization_type': 'property_tags', - 'authorized_for': 'All Meta properties', - 'property_tags': ['meta_network'], - 'url': 'https://meta-ads.com', + "authorization_type": "property_tags", + "authorized_for": "All Meta properties", + "property_tags": ["meta_network"], + "url": "https://meta-ads.com", } ], - 'contact': { - 'domain': 'meta.com', - 'email': 'adops@meta.com', - 'name': 'Meta Advertising Operations', - 'seller_id': 'pub-meta-12345', - 'tag_id': '12345', + "contact": { + "domain": "meta.com", + "email": "adops@meta.com", + "name": "Meta Advertising Operations", + "seller_id": "pub-meta-12345", + "tag_id": "12345", }, - 'last_updated': '2025-01-10T15:30:00Z', - 'properties': [ + "last_updated": "2025-01-10T15:30:00Z", + "properties": [ { - 'identifiers': [ - {'type': 'ios_bundle', 'value': 'com.burbn.instagram'}, - {'type': 'android_package', 'value': 'com.instagram.android'}, + "identifiers": [ + {"type": "ios_bundle", "value": "com.burbn.instagram"}, + {"type": "android_package", "value": "com.instagram.android"}, ], - 'name': 'Instagram', - 'property_type': 'mobile_app', - 'publisher_domain': 'instagram.com', - 'tags': ['meta_network', 'social_media'], + "name": "Instagram", + "property_type": "mobile_app", + "publisher_domain": "instagram.com", + "tags": ["meta_network", "social_media"], }, { - 'identifiers': [ - {'type': 'ios_bundle', 'value': 'com.facebook.Facebook'}, - {'type': 'android_package', 'value': 'com.facebook.katana'}, + "identifiers": [ + {"type": "ios_bundle", "value": "com.facebook.Facebook"}, + {"type": "android_package", "value": "com.facebook.katana"}, ], - 'name': 'Facebook', - 'property_type': 'mobile_app', - 'publisher_domain': 'facebook.com', - 'tags': ['meta_network', 'social_media'], + "name": "Facebook", + "property_type": "mobile_app", + "publisher_domain": "facebook.com", + "tags": ["meta_network", "social_media"], }, { - 'identifiers': [ - {'type': 'ios_bundle', 'value': 'net.whatsapp.WhatsApp'}, - {'type': 'android_package', 'value': 'com.whatsapp'}, + "identifiers": [ + {"type": "ios_bundle", "value": "net.whatsapp.WhatsApp"}, + {"type": "android_package", "value": "com.whatsapp"}, ], - 'name': 'WhatsApp', - 'property_type': 'mobile_app', - 'publisher_domain': 'whatsapp.com', - 'tags': ['meta_network', 'messaging'], + "name": "WhatsApp", + "property_type": "mobile_app", + "publisher_domain": "whatsapp.com", + "tags": ["meta_network", "messaging"], }, ], - 'tags': { - 'messaging': { - 'description': 'Messaging and communication apps', - 'name': 'Messaging Apps', + "tags": { + "messaging": { + "description": "Messaging and communication apps", + "name": "Messaging Apps", }, - 'meta_network': { - 'description': 'All Meta-owned properties', - 'name': 'Meta Network', + "meta_network": { + "description": "All Meta-owned properties", + "name": "Meta Network", }, - 'social_media': { - 'description': 'Social networking applications', - 'name': 'Social Media Apps', + "social_media": { + "description": "Social networking applications", + "name": "Social Media Apps", }, }, }, { - '$schema': '/schemas/2.6.0/adagents.json', - 'authorized_agents': [ + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ { - 'authorization_type': 'property_tags', - 'authorized_for': 'Tumblr corporate properties only', - 'property_tags': ['corporate'], - 'url': 'https://tumblr-sales.com', + "authorization_type": "property_tags", + "authorized_for": "Tumblr corporate properties only", + "property_tags": ["corporate"], + "url": "https://tumblr-sales.com", } ], - 'contact': {'name': 'Tumblr Advertising'}, - 'last_updated': '2025-01-10T16:00:00Z', - 'properties': [ + "contact": {"name": "Tumblr Advertising"}, + "last_updated": "2025-01-10T16:00:00Z", + "properties": [ { - 'identifiers': [{'type': 'domain', 'value': 'tumblr.com'}], - 'name': 'Tumblr Corporate', - 'property_type': 'website', - 'publisher_domain': 'tumblr.com', - 'tags': ['corporate'], + "identifiers": [{"type": "domain", "value": "tumblr.com"}], + "name": "Tumblr Corporate", + "property_type": "website", + "publisher_domain": "tumblr.com", + "tags": ["corporate"], } ], - 'tags': { - 'corporate': { - 'description': 'Tumblr-owned corporate properties (not user blogs)', - 'name': 'Corporate Properties', + "tags": { + "corporate": { + "description": "Tumblr-owned corporate properties (not user blogs)", + "name": "Corporate Properties", } }, }, { - '$schema': '/schemas/2.6.0/adagents.json', - 'authorized_agents': [ + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ { - 'authorization_type': 'publisher_properties', - 'authorized_for': 'CNN CTV properties via publisher authorization', - 'publisher_properties': [ + "authorization_type": "publisher_properties", + "authorized_for": "CNN CTV properties via publisher authorization", + "publisher_properties": [ { - 'property_ids': ['cnn_ctv_app'], - 'publisher_domain': 'cnn.com', - 'selection_type': 'by_id', + "property_ids": ["cnn_ctv_app"], + "publisher_domain": "cnn.com", + "selection_type": "by_id", } ], - 'url': 'https://agent.example/api', + "url": "https://agent.example/api", }, { - 'authorization_type': 'publisher_properties', - 'authorized_for': 'All CTV properties from multiple publishers', - 'publisher_properties': [ + "authorization_type": "publisher_properties", + "authorized_for": "All CTV properties from multiple publishers", + "publisher_properties": [ { - 'property_tags': ['ctv'], - 'publisher_domain': 'cnn.com', - 'selection_type': 'by_tag', + "property_tags": ["ctv"], + "publisher_domain": "cnn.com", + "selection_type": "by_tag", }, { - 'property_tags': ['ctv'], - 'publisher_domain': 'espn.com', - 'selection_type': 'by_tag', + "property_tags": ["ctv"], + "publisher_domain": "espn.com", + "selection_type": "by_tag", }, ], - 'url': 'https://agent.example/api', + "url": "https://agent.example/api", }, ], - 'contact': { - 'domain': 'agent.example', - 'email': 'sales@agent.example', - 'name': 'Example Third-Party Sales Agent', + "contact": { + "domain": "agent.example", + "email": "sales@agent.example", + "name": "Example Third-Party Sales Agent", + }, + "last_updated": "2025-01-10T17:00:00Z", + }, + { + "$schema": "/schemas/2.6.0/adagents.json", + "authorized_agents": [ + { + "authorization_type": "property_tags", + "authorized_for": "All news properties", + "property_tags": ["news"], + "url": "https://sales.news.example.com", + } + ], + "contact": { + "domain": "news.example.com", + "email": "adops@news.example.com", + "name": "Premium News Publisher", + }, + "last_updated": "2025-01-10T18:00:00Z", + "properties": [ + { + "identifiers": [{"type": "domain", "value": "news.example.com"}], + "name": "News Example", + "property_type": "website", + "publisher_domain": "news.example.com", + "tags": ["premium", "news"], + } + ], + "property_features": [ + { + "features": ["carbon_score", "sustainability_grade"], + "name": "Scope3", + "publisher_id": "pub_news_12345", + "url": "https://api.scope3.com", + }, + { + "features": [ + "tag_certified_against_fraud", + "tag_brand_safety_certified", + ], + "name": "TAG", + "url": "https://api.tagtoday.net", + }, + { + "features": ["gdpr_compliant", "tcf_registered", "ccpa_compliant"], + "name": "OneTrust", + "publisher_id": "ot_news_67890", + "url": "https://api.onetrust.com", + }, + ], + "tags": { + "news": { + "description": "News and journalism content", + "name": "News Properties", + }, + "premium": { + "description": "High-quality, brand-safe properties", + "name": "Premium Properties", + }, }, - 'last_updated': '2025-01-10T17:00:00Z', }, ], - title='Authorized Sales Agents', + title="Authorized Sales Agents", ), ] diff --git a/src/adcp/types/generated_poc/core/activation_key.py b/src/adcp/types/generated_poc/core/activation_key.py index b8509374..42d753d8 100644 --- a/src/adcp/types/generated_poc/core/activation_key.py +++ b/src/adcp/types/generated_poc/core/activation_key.py @@ -12,22 +12,22 @@ class ActivationKey1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) segment_id: Annotated[ str, - Field(description='The platform-specific segment identifier to use in campaign targeting'), + Field(description="The platform-specific segment identifier to use in campaign targeting"), ] - type: Annotated[Literal['segment_id'], Field(description='Segment ID based targeting')] + type: Annotated[Literal["segment_id"], Field(description="Segment ID based targeting")] class ActivationKey2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - key: Annotated[str, Field(description='The targeting parameter key')] - type: Annotated[Literal['key_value'], Field(description='Key-value pair based targeting')] - value: Annotated[str, Field(description='The targeting parameter value')] + key: Annotated[str, Field(description="The targeting parameter key")] + type: Annotated[Literal["key_value"], Field(description="Key-value pair based targeting")] + value: Annotated[str, Field(description="The targeting parameter value")] class ActivationKey(RootModel[ActivationKey1 | ActivationKey2]): @@ -35,6 +35,6 @@ class ActivationKey(RootModel[ActivationKey1 | ActivationKey2]): ActivationKey1 | ActivationKey2, Field( description="Universal identifier for using a signal on a destination platform. Can be either a segment ID or a key-value pair depending on the platform's targeting mechanism.", - title='Activation Key', + title="Activation Key", ), ] diff --git a/src/adcp/types/generated_poc/core/assets/audio_asset.py b/src/adcp/types/generated_poc/core/assets/audio_asset.py index 33a0ca65..de9a645d 100644 --- a/src/adcp/types/generated_poc/core/assets/audio_asset.py +++ b/src/adcp/types/generated_poc/core/assets/audio_asset.py @@ -12,15 +12,15 @@ class AudioAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bitrate_kbps: Annotated[ - int | None, Field(description='Audio bitrate in kilobits per second', ge=1) + int | None, Field(description="Audio bitrate in kilobits per second", ge=1) ] = None duration_ms: Annotated[ - int | None, Field(description='Audio duration in milliseconds', ge=0) + int | None, Field(description="Audio duration in milliseconds", ge=0) ] = None - format: Annotated[str | None, Field(description='Audio file format (mp3, wav, aac, etc.)')] = ( + format: Annotated[str | None, Field(description="Audio file format (mp3, wav, aac, etc.)")] = ( None ) - url: Annotated[AnyUrl, Field(description='URL to the audio asset')] + url: Annotated[AnyUrl, Field(description="URL to the audio asset")] diff --git a/src/adcp/types/generated_poc/core/assets/css_asset.py b/src/adcp/types/generated_poc/core/assets/css_asset.py index 91e797ae..64f8d30d 100644 --- a/src/adcp/types/generated_poc/core/assets/css_asset.py +++ b/src/adcp/types/generated_poc/core/assets/css_asset.py @@ -12,9 +12,9 @@ class CssAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - content: Annotated[str, Field(description='CSS content')] + content: Annotated[str, Field(description="CSS content")] media: Annotated[ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')") ] = None diff --git a/src/adcp/types/generated_poc/core/assets/daast_asset.py b/src/adcp/types/generated_poc/core/assets/daast_asset.py index 4b596033..c31154f4 100644 --- a/src/adcp/types/generated_poc/core/assets/daast_asset.py +++ b/src/adcp/types/generated_poc/core/assets/daast_asset.py @@ -15,49 +15,49 @@ class DaastAsset1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) companion_ads: Annotated[ - bool | None, Field(description='Whether companion display ads are included') + bool | None, Field(description="Whether companion display ads are included") ] = None daast_version: Annotated[ - daast_version_1.DaastVersion | None, Field(description='DAAST specification version') + daast_version_1.DaastVersion | None, Field(description="DAAST specification version") ] = None delivery_type: Annotated[ - Literal['url'], - Field(description='Discriminator indicating DAAST is delivered via URL endpoint'), + Literal["url"], + Field(description="Discriminator indicating DAAST is delivered via URL endpoint"), ] duration_ms: Annotated[ - int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0) + int | None, Field(description="Expected audio duration in milliseconds (if known)", ge=0) ] = None tracking_events: Annotated[ list[daast_tracking_event.DaastTrackingEvent] | None, - Field(description='Tracking events supported by this DAAST tag'), + Field(description="Tracking events supported by this DAAST tag"), ] = None - url: Annotated[AnyUrl, Field(description='URL endpoint that returns DAAST XML')] + url: Annotated[AnyUrl, Field(description="URL endpoint that returns DAAST XML")] class DaastAsset2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) companion_ads: Annotated[ - bool | None, Field(description='Whether companion display ads are included') + bool | None, Field(description="Whether companion display ads are included") ] = None - content: Annotated[str, Field(description='Inline DAAST XML content')] + content: Annotated[str, Field(description="Inline DAAST XML content")] daast_version: Annotated[ - daast_version_1.DaastVersion | None, Field(description='DAAST specification version') + daast_version_1.DaastVersion | None, Field(description="DAAST specification version") ] = None delivery_type: Annotated[ - Literal['inline'], - Field(description='Discriminator indicating DAAST is delivered as inline XML content'), + Literal["inline"], + Field(description="Discriminator indicating DAAST is delivered as inline XML content"), ] duration_ms: Annotated[ - int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0) + int | None, Field(description="Expected audio duration in milliseconds (if known)", ge=0) ] = None tracking_events: Annotated[ list[daast_tracking_event.DaastTrackingEvent] | None, - Field(description='Tracking events supported by this DAAST tag'), + Field(description="Tracking events supported by this DAAST tag"), ] = None @@ -65,7 +65,7 @@ class DaastAsset(RootModel[DaastAsset1 | DaastAsset2]): root: Annotated[ DaastAsset1 | DaastAsset2, Field( - description='DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving', - title='DAAST Asset', + description="DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving", + title="DAAST Asset", ), ] diff --git a/src/adcp/types/generated_poc/core/assets/html_asset.py b/src/adcp/types/generated_poc/core/assets/html_asset.py index f953a6db..dfc6c2c7 100644 --- a/src/adcp/types/generated_poc/core/assets/html_asset.py +++ b/src/adcp/types/generated_poc/core/assets/html_asset.py @@ -12,7 +12,7 @@ class HtmlAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - content: Annotated[str, Field(description='HTML content')] + content: Annotated[str, Field(description="HTML content")] version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None diff --git a/src/adcp/types/generated_poc/core/assets/image_asset.py b/src/adcp/types/generated_poc/core/assets/image_asset.py index 1af037fc..773e530e 100644 --- a/src/adcp/types/generated_poc/core/assets/image_asset.py +++ b/src/adcp/types/generated_poc/core/assets/image_asset.py @@ -12,12 +12,12 @@ class ImageAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - alt_text: Annotated[str | None, Field(description='Alternative text for accessibility')] = None + alt_text: Annotated[str | None, Field(description="Alternative text for accessibility")] = None format: Annotated[ - str | None, Field(description='Image file format (jpg, png, gif, webp, etc.)') + str | None, Field(description="Image file format (jpg, png, gif, webp, etc.)") ] = None - height: Annotated[int, Field(description='Height in pixels', ge=1)] - url: Annotated[AnyUrl, Field(description='URL to the image asset')] - width: Annotated[int, Field(description='Width in pixels', ge=1)] + height: Annotated[int, Field(description="Height in pixels", ge=1)] + url: Annotated[AnyUrl, Field(description="URL to the image asset")] + width: Annotated[int, Field(description="Width in pixels", ge=1)] diff --git a/src/adcp/types/generated_poc/core/assets/javascript_asset.py b/src/adcp/types/generated_poc/core/assets/javascript_asset.py index a382ad05..8c95b766 100644 --- a/src/adcp/types/generated_poc/core/assets/javascript_asset.py +++ b/src/adcp/types/generated_poc/core/assets/javascript_asset.py @@ -14,10 +14,10 @@ class JavascriptAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - content: Annotated[str, Field(description='JavaScript content')] + content: Annotated[str, Field(description="JavaScript content")] module_type: Annotated[ javascript_module_type.JavascriptModuleType | None, - Field(description='JavaScript module type'), + Field(description="JavaScript module type"), ] = None diff --git a/src/adcp/types/generated_poc/core/assets/text_asset.py b/src/adcp/types/generated_poc/core/assets/text_asset.py index f16ccfa3..553bd887 100644 --- a/src/adcp/types/generated_poc/core/assets/text_asset.py +++ b/src/adcp/types/generated_poc/core/assets/text_asset.py @@ -12,9 +12,9 @@ class TextAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - content: Annotated[str, Field(description='Text content')] + content: Annotated[str, Field(description="Text content")] language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = ( None ) diff --git a/src/adcp/types/generated_poc/core/assets/url_asset.py b/src/adcp/types/generated_poc/core/assets/url_asset.py index 7969e41f..10707be5 100644 --- a/src/adcp/types/generated_poc/core/assets/url_asset.py +++ b/src/adcp/types/generated_poc/core/assets/url_asset.py @@ -14,12 +14,12 @@ class UrlAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) description: Annotated[ - str | None, Field(description='Description of what this URL points to') + str | None, Field(description="Description of what this URL points to") ] = None - url: Annotated[AnyUrl, Field(description='URL reference')] + url: Annotated[AnyUrl, Field(description="URL reference")] url_type: Annotated[ url_asset_type.UrlAssetType | None, Field( diff --git a/src/adcp/types/generated_poc/core/assets/vast_asset.py b/src/adcp/types/generated_poc/core/assets/vast_asset.py index dcb24220..bbe8187e 100644 --- a/src/adcp/types/generated_poc/core/assets/vast_asset.py +++ b/src/adcp/types/generated_poc/core/assets/vast_asset.py @@ -15,51 +15,51 @@ class VastAsset1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) delivery_type: Annotated[ - Literal['url'], - Field(description='Discriminator indicating VAST is delivered via URL endpoint'), + Literal["url"], + Field(description="Discriminator indicating VAST is delivered via URL endpoint"), ] duration_ms: Annotated[ - int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0) + int | None, Field(description="Expected video duration in milliseconds (if known)", ge=0) ] = None tracking_events: Annotated[ list[vast_tracking_event.VastTrackingEvent] | None, - Field(description='Tracking events supported by this VAST tag'), + Field(description="Tracking events supported by this VAST tag"), ] = None - url: Annotated[AnyUrl, Field(description='URL endpoint that returns VAST XML')] + url: Annotated[AnyUrl, Field(description="URL endpoint that returns VAST XML")] vast_version: Annotated[ - vast_version_1.VastVersion | None, Field(description='VAST specification version') + vast_version_1.VastVersion | None, Field(description="VAST specification version") ] = None vpaid_enabled: Annotated[ bool | None, - Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'), + Field(description="Whether VPAID (Video Player-Ad Interface Definition) is supported"), ] = None class VastAsset2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - content: Annotated[str, Field(description='Inline VAST XML content')] + content: Annotated[str, Field(description="Inline VAST XML content")] delivery_type: Annotated[ - Literal['inline'], - Field(description='Discriminator indicating VAST is delivered as inline XML content'), + Literal["inline"], + Field(description="Discriminator indicating VAST is delivered as inline XML content"), ] duration_ms: Annotated[ - int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0) + int | None, Field(description="Expected video duration in milliseconds (if known)", ge=0) ] = None tracking_events: Annotated[ list[vast_tracking_event.VastTrackingEvent] | None, - Field(description='Tracking events supported by this VAST tag'), + Field(description="Tracking events supported by this VAST tag"), ] = None vast_version: Annotated[ - vast_version_1.VastVersion | None, Field(description='VAST specification version') + vast_version_1.VastVersion | None, Field(description="VAST specification version") ] = None vpaid_enabled: Annotated[ bool | None, - Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'), + Field(description="Whether VPAID (Video Player-Ad Interface Definition) is supported"), ] = None @@ -67,7 +67,7 @@ class VastAsset(RootModel[VastAsset1 | VastAsset2]): root: Annotated[ VastAsset1 | VastAsset2, Field( - description='VAST (Video Ad Serving Template) tag for third-party video ad serving', - title='VAST Asset', + description="VAST (Video Ad Serving Template) tag for third-party video ad serving", + title="VAST Asset", ), ] diff --git a/src/adcp/types/generated_poc/core/assets/video_asset.py b/src/adcp/types/generated_poc/core/assets/video_asset.py index 47fbcc67..259ba5f1 100644 --- a/src/adcp/types/generated_poc/core/assets/video_asset.py +++ b/src/adcp/types/generated_poc/core/assets/video_asset.py @@ -12,17 +12,17 @@ class VideoAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bitrate_kbps: Annotated[ - int | None, Field(description='Video bitrate in kilobits per second', ge=1) + int | None, Field(description="Video bitrate in kilobits per second", ge=1) ] = None duration_ms: Annotated[ - int | None, Field(description='Video duration in milliseconds', ge=1) + int | None, Field(description="Video duration in milliseconds", ge=1) ] = None - format: Annotated[str | None, Field(description='Video file format (mp4, webm, mov, etc.)')] = ( + format: Annotated[str | None, Field(description="Video file format (mp4, webm, mov, etc.)")] = ( None ) - height: Annotated[int, Field(description='Height in pixels', ge=1)] - url: Annotated[AnyUrl, Field(description='URL to the video asset')] - width: Annotated[int, Field(description='Width in pixels', ge=1)] + height: Annotated[int, Field(description="Height in pixels", ge=1)] + url: Annotated[AnyUrl, Field(description="URL to the video asset")] + width: Annotated[int, Field(description="Width in pixels", ge=1)] diff --git a/src/adcp/types/generated_poc/core/assets/webhook_asset.py b/src/adcp/types/generated_poc/core/assets/webhook_asset.py index d68f20ea..8982990e 100644 --- a/src/adcp/types/generated_poc/core/assets/webhook_asset.py +++ b/src/adcp/types/generated_poc/core/assets/webhook_asset.py @@ -20,34 +20,34 @@ class Security(AdCPBaseModel): str | None, Field(description="Header name for HMAC signature (e.g., 'X-Signature')") ] = None method: Annotated[ - webhook_security_method.WebhookSecurityMethod, Field(description='Authentication method') + webhook_security_method.WebhookSecurityMethod, Field(description="Authentication method") ] class WebhookAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - method: Annotated[http_method.HttpMethod | None, Field(description='HTTP method')] = ( + method: Annotated[http_method.HttpMethod | None, Field(description="HTTP method")] = ( http_method.HttpMethod.POST ) required_macros: Annotated[ list[str] | None, - Field(description='Universal macros that must be provided for webhook to function'), + Field(description="Universal macros that must be provided for webhook to function"), ] = None response_type: Annotated[ webhook_response_type.WebhookResponseType, - Field(description='Expected content type of webhook response'), + Field(description="Expected content type of webhook response"), ] - security: Annotated[Security, Field(description='Security configuration for webhook calls')] + security: Annotated[Security, Field(description="Security configuration for webhook calls")] supported_macros: Annotated[ list[str] | None, Field( - description='Universal macros that can be passed to webhook (e.g., {DEVICE_TYPE}, {COUNTRY})' + description="Universal macros that can be passed to webhook (e.g., {DEVICE_TYPE}, {COUNTRY})" ), ] = None timeout_ms: Annotated[ int | None, - Field(description='Maximum time to wait for response in milliseconds', ge=10, le=5000), + Field(description="Maximum time to wait for response in milliseconds", ge=10, le=5000), ] = 500 - url: Annotated[AnyUrl, Field(description='Webhook URL to call for dynamic content')] + url: Annotated[AnyUrl, Field(description="Webhook URL to call for dynamic content")] diff --git a/src/adcp/types/generated_poc/core/async_response_data.py b/src/adcp/types/generated_poc/core/async_response_data.py index 3393e9fd..fa25e6df 100644 --- a/src/adcp/types/generated_poc/core/async_response_data.py +++ b/src/adcp/types/generated_poc/core/async_response_data.py @@ -66,7 +66,7 @@ class AdcpAsyncResponseData( | sync_creatives_async_response_input_required.SyncCreativesInputRequired | sync_creatives_async_response_submitted.SyncCreativesSubmitted, Field( - description='Union of all possible data payloads for async task webhook responses. For completed/failed statuses, use the main task response schema. For working/input-required/submitted, use the status-specific schemas.', - title='AdCP Async Response Data', + description="Union of all possible data payloads for async task webhook responses. For completed/failed statuses, use the main task response schema. For working/input-required/submitted, use the status-specific schemas.", + title="AdCP Async Response Data", ), ] diff --git a/src/adcp/types/generated_poc/core/brand_manifest.py b/src/adcp/types/generated_poc/core/brand_manifest.py index d009a778..56d13b86 100644 --- a/src/adcp/types/generated_poc/core/brand_manifest.py +++ b/src/adcp/types/generated_poc/core/brand_manifest.py @@ -15,61 +15,61 @@ class Asset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - asset_id: Annotated[str, Field(description='Unique identifier for this asset')] + asset_id: Annotated[str, Field(description="Unique identifier for this asset")] asset_type: Annotated[ asset_content_type.AssetContentType, Field( - description='Type of asset. Note: Brand manifests typically contain basic media assets (image, video, audio, text). Code assets (html, javascript, css) and ad markup (vast, daast) are usually not part of brand asset libraries.' + description="Type of asset. Note: Brand manifests typically contain basic media assets (image, video, audio, text). Code assets (html, javascript, css) and ad markup (vast, daast) are usually not part of brand asset libraries." ), ] - description: Annotated[str | None, Field(description='Asset description or usage notes')] = None + description: Annotated[str | None, Field(description="Asset description or usage notes")] = None duration_seconds: Annotated[ - float | None, Field(description='Video/audio duration in seconds') + float | None, Field(description="Video/audio duration in seconds") ] = None - file_size_bytes: Annotated[int | None, Field(description='File size in bytes')] = None + file_size_bytes: Annotated[int | None, Field(description="File size in bytes")] = None format: Annotated[str | None, Field(description="File format (e.g., 'jpg', 'mp4', 'mp3')")] = ( None ) - height: Annotated[int | None, Field(description='Image/video height in pixels')] = None + height: Annotated[int | None, Field(description="Image/video height in pixels")] = None metadata: Annotated[ - dict[str, Any] | None, Field(description='Additional asset-specific metadata') + dict[str, Any] | None, Field(description="Additional asset-specific metadata") ] = None - name: Annotated[str | None, Field(description='Human-readable asset name')] = None + name: Annotated[str | None, Field(description="Human-readable asset name")] = None tags: Annotated[ list[str] | None, Field( description="Tags for asset discovery (e.g., 'holiday', 'lifestyle', 'product_shot')" ), ] = None - url: Annotated[AnyUrl, Field(description='URL to CDN-hosted asset file')] - width: Annotated[int | None, Field(description='Image/video width in pixels')] = None + url: Annotated[AnyUrl, Field(description="URL to CDN-hosted asset file")] + width: Annotated[int | None, Field(description="Image/video width in pixels")] = None class Colors(AdCPBaseModel): accent: Annotated[ - str | None, Field(description='Accent color (hex format)', pattern='^#[0-9A-Fa-f]{6}$') + str | None, Field(description="Accent color (hex format)", pattern="^#[0-9A-Fa-f]{6}$") ] = None background: Annotated[ - str | None, Field(description='Background color (hex format)', pattern='^#[0-9A-Fa-f]{6}$') + str | None, Field(description="Background color (hex format)", pattern="^#[0-9A-Fa-f]{6}$") ] = None primary: Annotated[ str | None, - Field(description='Primary brand color (hex format)', pattern='^#[0-9A-Fa-f]{6}$'), + Field(description="Primary brand color (hex format)", pattern="^#[0-9A-Fa-f]{6}$"), ] = None secondary: Annotated[ str | None, - Field(description='Secondary brand color (hex format)', pattern='^#[0-9A-Fa-f]{6}$'), + Field(description="Secondary brand color (hex format)", pattern="^#[0-9A-Fa-f]{6}$"), ] = None text: Annotated[ - str | None, Field(description='Text color (hex format)', pattern='^#[0-9A-Fa-f]{6}$') + str | None, Field(description="Text color (hex format)", pattern="^#[0-9A-Fa-f]{6}$") ] = None class Contact(AdCPBaseModel): - email: Annotated[EmailStr | None, Field(description='Contact email')] = None - phone: Annotated[str | None, Field(description='Contact phone number')] = None + email: Annotated[EmailStr | None, Field(description="Contact email")] = None + phone: Annotated[str | None, Field(description="Contact phone number")] = None class Disclaimer(AdCPBaseModel): @@ -79,92 +79,92 @@ class Disclaimer(AdCPBaseModel): description="When this disclaimer applies (e.g., 'financial_products', 'health_claims', 'all')" ), ] = None - required: Annotated[bool | None, Field(description='Whether this disclaimer must appear')] = ( + required: Annotated[bool | None, Field(description="Whether this disclaimer must appear")] = ( True ) - text: Annotated[str, Field(description='Disclaimer text')] + text: Annotated[str, Field(description="Disclaimer text")] class Fonts(AdCPBaseModel): font_urls: Annotated[ - list[AnyUrl] | None, Field(description='URLs to web font files if using custom fonts') + list[AnyUrl] | None, Field(description="URLs to web font files if using custom fonts") ] = None - primary: Annotated[str | None, Field(description='Primary font family name')] = None - secondary: Annotated[str | None, Field(description='Secondary font family name')] = None + primary: Annotated[str | None, Field(description="Primary font family name")] = None + secondary: Annotated[str | None, Field(description="Secondary font family name")] = None class Logo(AdCPBaseModel): - height: Annotated[int | None, Field(description='Logo height in pixels')] = None + height: Annotated[int | None, Field(description="Logo height in pixels")] = None tags: Annotated[ list[str] | None, Field( description="Semantic tags describing the logo variant (e.g., 'dark', 'light', 'square', 'horizontal', 'icon')" ), ] = None - url: Annotated[AnyUrl, Field(description='URL to the logo asset')] - width: Annotated[int | None, Field(description='Logo width in pixels')] = None + url: Annotated[AnyUrl, Field(description="URL to the logo asset")] + width: Annotated[int | None, Field(description="Logo width in pixels")] = None class Metadata(AdCPBaseModel): created_date: Annotated[ - AwareDatetime | None, Field(description='When this brand manifest was created') + AwareDatetime | None, Field(description="When this brand manifest was created") ] = None updated_date: Annotated[ - AwareDatetime | None, Field(description='When this brand manifest was last updated') + AwareDatetime | None, Field(description="When this brand manifest was last updated") ] = None - version: Annotated[str | None, Field(description='Brand card version number')] = None + version: Annotated[str | None, Field(description="Brand card version number")] = None class FeedFormat(Enum): - google_merchant_center = 'google_merchant_center' - facebook_catalog = 'facebook_catalog' - custom = 'custom' + google_merchant_center = "google_merchant_center" + facebook_catalog = "facebook_catalog" + custom = "custom" class UpdateFrequency(Enum): - realtime = 'realtime' - hourly = 'hourly' - daily = 'daily' - weekly = 'weekly' + realtime = "realtime" + hourly = "hourly" + daily = "daily" + weekly = "weekly" class ProductCatalog(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) categories: Annotated[ list[str] | None, - Field(description='Product categories available in the catalog (for filtering)'), + Field(description="Product categories available in the catalog (for filtering)"), ] = None - feed_format: Annotated[FeedFormat | None, Field(description='Format of the product feed')] = ( + feed_format: Annotated[FeedFormat | None, Field(description="Format of the product feed")] = ( FeedFormat.google_merchant_center ) - feed_url: Annotated[AnyUrl, Field(description='URL to product catalog feed')] + feed_url: Annotated[AnyUrl, Field(description="URL to product catalog feed")] last_updated: Annotated[ - AwareDatetime | None, Field(description='When the product catalog was last updated') + AwareDatetime | None, Field(description="When the product catalog was last updated") ] = None update_frequency: Annotated[ - UpdateFrequency | None, Field(description='How frequently the product catalog is updated') + UpdateFrequency | None, Field(description="How frequently the product catalog is updated") ] = None class BrandManifest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assets: Annotated[ list[Asset] | None, Field( - description='Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files.' + description="Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files." ), ] = None - colors: Annotated[Colors | None, Field(description='Brand color palette')] = None - contact: Annotated[Contact | None, Field(description='Brand contact information')] = None + colors: Annotated[Colors | None, Field(description="Brand color palette")] = None + contact: Annotated[Contact | None, Field(description="Brand contact information")] = None disclaimers: Annotated[ list[Disclaimer] | None, - Field(description='Legal disclaimers or required text that must appear in creatives'), + Field(description="Legal disclaimers or required text that must appear in creatives"), ] = None - fonts: Annotated[Fonts | None, Field(description='Brand typography guidelines')] = None + fonts: Annotated[Fonts | None, Field(description="Brand typography guidelines")] = None industry: Annotated[ str | None, Field( @@ -173,19 +173,19 @@ class BrandManifest(AdCPBaseModel): ] = None logos: Annotated[ list[Logo] | None, - Field(description='Brand logo assets with semantic tags for different use cases'), + Field(description="Brand logo assets with semantic tags for different use cases"), ] = None - metadata: Annotated[Metadata | None, Field(description='Additional brand metadata')] = None - name: Annotated[str, Field(description='Brand or business name')] + metadata: Annotated[Metadata | None, Field(description="Additional brand metadata")] = None + name: Annotated[str, Field(description="Brand or business name")] product_catalog: Annotated[ ProductCatalog | None, Field( - description='Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection.' + description="Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection." ), ] = None - tagline: Annotated[str | None, Field(description='Brand tagline or slogan')] = None + tagline: Annotated[str | None, Field(description="Brand tagline or slogan")] = None target_audience: Annotated[ - str | None, Field(description='Primary target audience description') + str | None, Field(description="Primary target audience description") ] = None tone: Annotated[ str | None, @@ -196,6 +196,6 @@ class BrandManifest(AdCPBaseModel): url: Annotated[ AnyUrl | None, Field( - description='Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL.' + description="Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL." ), ] = None diff --git a/src/adcp/types/generated_poc/core/brand_manifest_ref.py b/src/adcp/types/generated_poc/core/brand_manifest_ref.py index 850dba23..a1fb341a 100644 --- a/src/adcp/types/generated_poc/core/brand_manifest_ref.py +++ b/src/adcp/types/generated_poc/core/brand_manifest_ref.py @@ -15,21 +15,21 @@ class BrandManifestReference(RootModel[brand_manifest.BrandManifest | AnyUrl]): root: Annotated[ brand_manifest.BrandManifest | AnyUrl, Field( - description='Brand manifest provided either as an inline object or a URL string pointing to a hosted manifest', + description="Brand manifest provided either as an inline object or a URL string pointing to a hosted manifest", examples=[ { - 'data': { - 'colors': {'primary': '#FF6B35'}, - 'name': 'ACME Corporation', - 'url': 'https://acmecorp.com', + "data": { + "colors": {"primary": "#FF6B35"}, + "name": "ACME Corporation", + "url": "https://acmecorp.com", }, - 'description': 'Inline brand manifest', + "description": "Inline brand manifest", }, { - 'data': 'https://cdn.acmecorp.com/brand-manifest.json', - 'description': 'URL string reference to hosted manifest', + "data": "https://cdn.acmecorp.com/brand-manifest.json", + "description": "URL string reference to hosted manifest", }, ], - title='Brand Manifest Reference', + title="Brand Manifest Reference", ), ] diff --git a/src/adcp/types/generated_poc/core/context.py b/src/adcp/types/generated_poc/core/context.py index 5a98be66..a331704d 100644 --- a/src/adcp/types/generated_poc/core/context.py +++ b/src/adcp/types/generated_poc/core/context.py @@ -10,5 +10,5 @@ class ContextObject(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) diff --git a/src/adcp/types/generated_poc/core/creative_asset.py b/src/adcp/types/generated_poc/core/creative_asset.py index fc123911..7575148d 100644 --- a/src/adcp/types/generated_poc/core/creative_asset.py +++ b/src/adcp/types/generated_poc/core/creative_asset.py @@ -27,26 +27,26 @@ class Input(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context_description: Annotated[ str | None, - Field(description='Natural language description of the context for AI-generated content'), + Field(description="Natural language description of the context for AI-generated content"), ] = None macros: Annotated[ - dict[str, str] | None, Field(description='Macro values to apply for this preview') + dict[str, str] | None, Field(description="Macro values to apply for this preview") ] = None - name: Annotated[str, Field(description='Human-readable name for this preview variant')] + name: Annotated[str, Field(description="Human-readable name for this preview variant")] class CreativeAsset(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) approved: Annotated[ bool | None, Field( - description='For generative creatives: set to true to approve and finalize, false to request regeneration with updated assets/message. Omit for non-generative creatives.' + description="For generative creatives: set to true to approve and finalize, false to request regeneration with updated assets/message. Omit for non-generative creatives." ), ] = None assets: Annotated[ @@ -64,22 +64,22 @@ class CreativeAsset(AdCPBaseModel): | promoted_offerings.PromotedOfferings | url_asset.UrlAsset, ], - Field(description='Assets required by the format, keyed by asset_role'), + Field(description="Assets required by the format, keyed by asset_role"), ] - creative_id: Annotated[str, Field(description='Unique identifier for the creative')] + creative_id: Annotated[str, Field(description="Unique identifier for the creative")] format_id: Annotated[ format_id_1.FormatId, Field( - description='Format identifier specifying which format this creative conforms to. Can be: (1) concrete format_id referencing a format with fixed dimensions, (2) template format_id referencing a template format, or (3) parameterized format_id with dimensions/duration parameters for template formats.' + description="Format identifier specifying which format this creative conforms to. Can be: (1) concrete format_id referencing a format with fixed dimensions, (2) template format_id referencing a template format, or (3) parameterized format_id with dimensions/duration parameters for template formats." ), ] inputs: Annotated[ list[Input] | None, Field( - description='Preview contexts for generative formats - defines what scenarios to generate previews for' + description="Preview contexts for generative formats - defines what scenarios to generate previews for" ), ] = None - name: Annotated[str, Field(description='Human-readable creative name')] + name: Annotated[str, Field(description="Human-readable creative name")] placement_ids: Annotated[ list[str] | None, Field( @@ -88,12 +88,12 @@ class CreativeAsset(AdCPBaseModel): ), ] = None tags: Annotated[ - list[str] | None, Field(description='User-defined tags for organization and searchability') + list[str] | None, Field(description="User-defined tags for organization and searchability") ] = None weight: Annotated[ float | None, Field( - description='Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.', + description="Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.", ge=0.0, le=100.0, ), diff --git a/src/adcp/types/generated_poc/core/creative_assignment.py b/src/adcp/types/generated_poc/core/creative_assignment.py index ed6aa184..c8fd8338 100644 --- a/src/adcp/types/generated_poc/core/creative_assignment.py +++ b/src/adcp/types/generated_poc/core/creative_assignment.py @@ -12,9 +12,9 @@ class CreativeAssignment(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - creative_id: Annotated[str, Field(description='Unique identifier for the creative')] + creative_id: Annotated[str, Field(description="Unique identifier for the creative")] placement_ids: Annotated[ list[str] | None, Field( @@ -23,5 +23,5 @@ class CreativeAssignment(AdCPBaseModel): ), ] = None weight: Annotated[ - float | None, Field(description='Delivery weight for this creative', ge=0.0, le=100.0) + float | None, Field(description="Delivery weight for this creative", ge=0.0, le=100.0) ] = None diff --git a/src/adcp/types/generated_poc/core/creative_filters.py b/src/adcp/types/generated_poc/core/creative_filters.py index 030382bb..ba09200f 100644 --- a/src/adcp/types/generated_poc/core/creative_filters.py +++ b/src/adcp/types/generated_poc/core/creative_filters.py @@ -14,73 +14,73 @@ class CreativeFilters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assigned_to_package: Annotated[ - str | None, Field(description='Filter creatives assigned to this specific package') + str | None, Field(description="Filter creatives assigned to this specific package") ] = None assigned_to_packages: Annotated[ - list[str] | None, Field(description='Filter creatives assigned to any of these packages') + list[str] | None, Field(description="Filter creatives assigned to any of these packages") ] = None buyer_refs: Annotated[ list[str] | None, Field( - description='Filter creatives assigned to media buys with any of these buyer references' + description="Filter creatives assigned to media buys with any of these buyer references" ), ] = None created_after: Annotated[ AwareDatetime | None, - Field(description='Filter creatives created after this date (ISO 8601)'), + Field(description="Filter creatives created after this date (ISO 8601)"), ] = None created_before: Annotated[ AwareDatetime | None, - Field(description='Filter creatives created before this date (ISO 8601)'), + Field(description="Filter creatives created before this date (ISO 8601)"), ] = None creative_ids: Annotated[ - list[str] | None, Field(description='Filter by specific creative IDs', max_length=100) + list[str] | None, Field(description="Filter by specific creative IDs", max_length=100) ] = None format: Annotated[ str | None, - Field(description='Filter by creative format type (e.g., video, audio, display)'), + Field(description="Filter by creative format type (e.g., video, audio, display)"), ] = None formats: Annotated[ - list[str] | None, Field(description='Filter by multiple creative format types') + list[str] | None, Field(description="Filter by multiple creative format types") ] = None has_performance_data: Annotated[ - bool | None, Field(description='Filter creatives that have performance data when true') + bool | None, Field(description="Filter creatives that have performance data when true") ] = None media_buy_ids: Annotated[ - list[str] | None, Field(description='Filter creatives assigned to any of these media buys') + list[str] | None, Field(description="Filter creatives assigned to any of these media buys") ] = None name_contains: Annotated[ str | None, - Field(description='Filter by creative names containing this text (case-insensitive)'), + Field(description="Filter by creative names containing this text (case-insensitive)"), ] = None status: Annotated[ creative_status.CreativeStatus | None, - Field(description='Filter by creative approval status'), + Field(description="Filter by creative approval status"), ] = None statuses: Annotated[ list[creative_status.CreativeStatus] | None, - Field(description='Filter by multiple creative statuses'), + Field(description="Filter by multiple creative statuses"), ] = None tags: Annotated[ - list[str] | None, Field(description='Filter by creative tags (all tags must match)') + list[str] | None, Field(description="Filter by creative tags (all tags must match)") ] = None tags_any: Annotated[ - list[str] | None, Field(description='Filter by creative tags (any tag must match)') + list[str] | None, Field(description="Filter by creative tags (any tag must match)") ] = None unassigned: Annotated[ bool | None, Field( - description='Filter for unassigned creatives when true, assigned creatives when false' + description="Filter for unassigned creatives when true, assigned creatives when false" ), ] = None updated_after: Annotated[ AwareDatetime | None, - Field(description='Filter creatives last updated after this date (ISO 8601)'), + Field(description="Filter creatives last updated after this date (ISO 8601)"), ] = None updated_before: Annotated[ AwareDatetime | None, - Field(description='Filter creatives last updated before this date (ISO 8601)'), + Field(description="Filter creatives last updated before this date (ISO 8601)"), ] = None diff --git a/src/adcp/types/generated_poc/core/creative_manifest.py b/src/adcp/types/generated_poc/core/creative_manifest.py index ef22303a..de1865b9 100644 --- a/src/adcp/types/generated_poc/core/creative_manifest.py +++ b/src/adcp/types/generated_poc/core/creative_manifest.py @@ -29,7 +29,7 @@ class CreativeManifest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assets: Annotated[ dict[ @@ -61,6 +61,6 @@ class CreativeManifest(AdCPBaseModel): promoted_offering: Annotated[ str | None, Field( - description='Product name or offering being advertised. Maps to promoted_offerings in create_media_buy request to associate creative with the product being promoted.' + description="Product name or offering being advertised. Maps to promoted_offerings in create_media_buy request to associate creative with the product being promoted." ), ] = None diff --git a/src/adcp/types/generated_poc/core/creative_policy.py b/src/adcp/types/generated_poc/core/creative_policy.py index d3a38cb9..6126fbc3 100644 --- a/src/adcp/types/generated_poc/core/creative_policy.py +++ b/src/adcp/types/generated_poc/core/creative_policy.py @@ -14,15 +14,15 @@ class CreativePolicy(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) co_branding: Annotated[ - co_branding_requirement.CoBrandingRequirement, Field(description='Co-branding requirement') + co_branding_requirement.CoBrandingRequirement, Field(description="Co-branding requirement") ] landing_page: Annotated[ landing_page_requirement.LandingPageRequirement, - Field(description='Landing page requirements'), + Field(description="Landing page requirements"), ] templates_available: Annotated[ - bool, Field(description='Whether creative templates are provided') + bool, Field(description="Whether creative templates are provided") ] diff --git a/src/adcp/types/generated_poc/core/delivery_metrics.py b/src/adcp/types/generated_poc/core/delivery_metrics.py index 33cdd893..888dd7e8 100644 --- a/src/adcp/types/generated_poc/core/delivery_metrics.py +++ b/src/adcp/types/generated_poc/core/delivery_metrics.py @@ -12,15 +12,15 @@ class VenueBreakdownItem(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - impressions: Annotated[int, Field(description='Impressions delivered at this venue', ge=0)] - loop_plays: Annotated[int | None, Field(description='Loop plays at this venue', ge=0)] = None + impressions: Annotated[int, Field(description="Impressions delivered at this venue", ge=0)] + loop_plays: Annotated[int | None, Field(description="Loop plays at this venue", ge=0)] = None screens_used: Annotated[ - int | None, Field(description='Number of screens used at this venue', ge=0) + int | None, Field(description="Number of screens used at this venue", ge=0) ] = None - venue_id: Annotated[str, Field(description='Venue identifier')] - venue_name: Annotated[str | None, Field(description='Human-readable venue name')] = None + venue_id: Annotated[str, Field(description="Venue identifier")] + venue_name: Annotated[str | None, Field(description="Human-readable venue name")] = None venue_type: Annotated[ str | None, Field(description="Venue type (e.g., 'airport', 'transit', 'retail', 'billboard')"), @@ -29,83 +29,83 @@ class VenueBreakdownItem(AdCPBaseModel): class DoohMetrics(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) calculation_notes: Annotated[ - str | None, Field(description='Explanation of how DOOH impressions were calculated') + str | None, Field(description="Explanation of how DOOH impressions were calculated") ] = None loop_plays: Annotated[ - int | None, Field(description='Number of times ad played in rotation', ge=0) + int | None, Field(description="Number of times ad played in rotation", ge=0) ] = None screen_time_seconds: Annotated[ - int | None, Field(description='Total display time in seconds', ge=0) + int | None, Field(description="Total display time in seconds", ge=0) ] = None screens_used: Annotated[ - int | None, Field(description='Number of unique screens displaying the ad', ge=0) + int | None, Field(description="Number of unique screens displaying the ad", ge=0) ] = None sov_achieved: Annotated[ float | None, - Field(description='Actual share of voice delivered (0.0 to 1.0)', ge=0.0, le=1.0), + Field(description="Actual share of voice delivered (0.0 to 1.0)", ge=0.0, le=1.0), ] = None venue_breakdown: Annotated[ - list[VenueBreakdownItem] | None, Field(description='Per-venue performance breakdown') + list[VenueBreakdownItem] | None, Field(description="Per-venue performance breakdown") ] = None class QuartileData(AdCPBaseModel): - q1_views: Annotated[float | None, Field(description='25% completion views', ge=0.0)] = None - q2_views: Annotated[float | None, Field(description='50% completion views', ge=0.0)] = None - q3_views: Annotated[float | None, Field(description='75% completion views', ge=0.0)] = None - q4_views: Annotated[float | None, Field(description='100% completion views', ge=0.0)] = None + q1_views: Annotated[float | None, Field(description="25% completion views", ge=0.0)] = None + q2_views: Annotated[float | None, Field(description="50% completion views", ge=0.0)] = None + q3_views: Annotated[float | None, Field(description="75% completion views", ge=0.0)] = None + q4_views: Annotated[float | None, Field(description="100% completion views", ge=0.0)] = None class DeliveryMetrics(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - clicks: Annotated[float | None, Field(description='Total clicks', ge=0.0)] = None + clicks: Annotated[float | None, Field(description="Total clicks", ge=0.0)] = None completed_views: Annotated[ - float | None, Field(description='100% completions (for CPCV)', ge=0.0) + float | None, Field(description="100% completions (for CPCV)", ge=0.0) ] = None completion_rate: Annotated[ float | None, - Field(description='Completion rate (completed_views/impressions)', ge=0.0, le=1.0), + Field(description="Completion rate (completed_views/impressions)", ge=0.0, le=1.0), ] = None conversions: Annotated[ float | None, - Field(description='Conversions (reserved for future CPA pricing support)', ge=0.0), + Field(description="Conversions (reserved for future CPA pricing support)", ge=0.0), ] = None ctr: Annotated[ - float | None, Field(description='Click-through rate (clicks/impressions)', ge=0.0, le=1.0) + float | None, Field(description="Click-through rate (clicks/impressions)", ge=0.0, le=1.0) ] = None dooh_metrics: Annotated[ DoohMetrics | None, - Field(description='DOOH-specific metrics (only included for DOOH campaigns)'), + Field(description="DOOH-specific metrics (only included for DOOH campaigns)"), ] = None frequency: Annotated[ float | None, Field( - description='Average frequency per individual (typically measured over campaign duration, but can vary by measurement provider)', + description="Average frequency per individual (typically measured over campaign duration, but can vary by measurement provider)", ge=0.0, ), ] = None grps: Annotated[ - float | None, Field(description='Gross Rating Points delivered (for CPP)', ge=0.0) + float | None, Field(description="Gross Rating Points delivered (for CPP)", ge=0.0) ] = None - impressions: Annotated[float | None, Field(description='Impressions delivered', ge=0.0)] = None + impressions: Annotated[float | None, Field(description="Impressions delivered", ge=0.0)] = None leads: Annotated[ float | None, - Field(description='Leads generated (reserved for future CPL pricing support)', ge=0.0), + Field(description="Leads generated (reserved for future CPL pricing support)", ge=0.0), ] = None quartile_data: Annotated[ - QuartileData | None, Field(description='Video quartile completion data') + QuartileData | None, Field(description="Video quartile completion data") ] = None reach: Annotated[ float | None, Field( - description='Unique reach - units depend on measurement provider (e.g., individuals, households, devices, cookies). See delivery_measurement.provider for methodology.', + description="Unique reach - units depend on measurement provider (e.g., individuals, households, devices, cookies). See delivery_measurement.provider for methodology.", ge=0.0, ), ] = None - spend: Annotated[float | None, Field(description='Amount spent', ge=0.0)] = None - views: Annotated[float | None, Field(description='Views at threshold (for CPV)', ge=0.0)] = None + spend: Annotated[float | None, Field(description="Amount spent", ge=0.0)] = None + views: Annotated[float | None, Field(description="Views at threshold (for CPV)", ge=0.0)] = None diff --git a/src/adcp/types/generated_poc/core/deployment.py b/src/adcp/types/generated_poc/core/deployment.py index b3c05447..2c4bd806 100644 --- a/src/adcp/types/generated_poc/core/deployment.py +++ b/src/adcp/types/generated_poc/core/deployment.py @@ -14,65 +14,65 @@ class Deployment1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - account: Annotated[str | None, Field(description='Account identifier if applicable')] = None + account: Annotated[str | None, Field(description="Account identifier if applicable")] = None activation_key: Annotated[ activation_key_1.ActivationKey | None, Field( - description='The key to use for targeting. Only present if is_live=true AND requester has access to this deployment.' + description="The key to use for targeting. Only present if is_live=true AND requester has access to this deployment." ), ] = None deployed_at: Annotated[ AwareDatetime | None, - Field(description='Timestamp when activation completed (if is_live=true)'), + Field(description="Timestamp when activation completed (if is_live=true)"), ] = None estimated_activation_duration_minutes: Annotated[ float | None, Field( - description='Estimated time to activate if not live, or to complete activation if in progress', + description="Estimated time to activate if not live, or to complete activation if in progress", ge=0.0, ), ] = None is_live: Annotated[ - bool, Field(description='Whether signal is currently active on this deployment') + bool, Field(description="Whether signal is currently active on this deployment") ] - platform: Annotated[str, Field(description='Platform identifier for DSPs')] + platform: Annotated[str, Field(description="Platform identifier for DSPs")] type: Annotated[ - Literal['platform'], - Field(description='Discriminator indicating this is a platform-based deployment'), + Literal["platform"], + Field(description="Discriminator indicating this is a platform-based deployment"), ] class Deployment2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - account: Annotated[str | None, Field(description='Account identifier if applicable')] = None + account: Annotated[str | None, Field(description="Account identifier if applicable")] = None activation_key: Annotated[ activation_key_1.ActivationKey | None, Field( - description='The key to use for targeting. Only present if is_live=true AND requester has access to this deployment.' + description="The key to use for targeting. Only present if is_live=true AND requester has access to this deployment." ), ] = None - agent_url: Annotated[AnyUrl, Field(description='URL identifying the deployment agent')] + agent_url: Annotated[AnyUrl, Field(description="URL identifying the deployment agent")] deployed_at: Annotated[ AwareDatetime | None, - Field(description='Timestamp when activation completed (if is_live=true)'), + Field(description="Timestamp when activation completed (if is_live=true)"), ] = None estimated_activation_duration_minutes: Annotated[ float | None, Field( - description='Estimated time to activate if not live, or to complete activation if in progress', + description="Estimated time to activate if not live, or to complete activation if in progress", ge=0.0, ), ] = None is_live: Annotated[ - bool, Field(description='Whether signal is currently active on this deployment') + bool, Field(description="Whether signal is currently active on this deployment") ] type: Annotated[ - Literal['agent'], - Field(description='Discriminator indicating this is an agent URL-based deployment'), + Literal["agent"], + Field(description="Discriminator indicating this is an agent URL-based deployment"), ] @@ -80,7 +80,7 @@ class Deployment(RootModel[Deployment1 | Deployment2]): root: Annotated[ Deployment1 | Deployment2, Field( - description='A signal deployment to a specific deployment target with activation status and key', - title='Deployment', + description="A signal deployment to a specific deployment target with activation status and key", + title="Deployment", ), ] diff --git a/src/adcp/types/generated_poc/core/destination.py b/src/adcp/types/generated_poc/core/destination.py index 2a811ba3..ee52b210 100644 --- a/src/adcp/types/generated_poc/core/destination.py +++ b/src/adcp/types/generated_poc/core/destination.py @@ -12,34 +12,34 @@ class Destination1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) account: Annotated[ - str | None, Field(description='Optional account identifier on the platform') + str | None, Field(description="Optional account identifier on the platform") ] = None platform: Annotated[ str, Field(description="Platform identifier for DSPs (e.g., 'the-trade-desk', 'amazon-dsp')"), ] type: Annotated[ - Literal['platform'], - Field(description='Discriminator indicating this is a platform-based deployment'), + Literal["platform"], + Field(description="Discriminator indicating this is a platform-based deployment"), ] class Destination2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) account: Annotated[ - str | None, Field(description='Optional account identifier on the agent') + str | None, Field(description="Optional account identifier on the agent") ] = None agent_url: Annotated[ - AnyUrl, Field(description='URL identifying the deployment agent (for sales agents, etc.)') + AnyUrl, Field(description="URL identifying the deployment agent (for sales agents, etc.)") ] type: Annotated[ - Literal['agent'], - Field(description='Discriminator indicating this is an agent URL-based deployment'), + Literal["agent"], + Field(description="Discriminator indicating this is an agent URL-based deployment"), ] @@ -47,7 +47,7 @@ class Destination(RootModel[Destination1 | Destination2]): root: Annotated[ Destination1 | Destination2, Field( - description='A deployment target where signals can be activated (DSP, sales agent, etc.)', - title='Destination', + description="A deployment target where signals can be activated (DSP, sales agent, etc.)", + title="Destination", ), ] diff --git a/src/adcp/types/generated_poc/core/error.py b/src/adcp/types/generated_poc/core/error.py index 13c44841..134e5683 100644 --- a/src/adcp/types/generated_poc/core/error.py +++ b/src/adcp/types/generated_poc/core/error.py @@ -12,18 +12,18 @@ class Error(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - code: Annotated[str, Field(description='Error code for programmatic handling')] + code: Annotated[str, Field(description="Error code for programmatic handling")] details: Annotated[ - dict[str, Any] | None, Field(description='Additional task-specific error details') + dict[str, Any] | None, Field(description="Additional task-specific error details") ] = None field: Annotated[ str | None, Field(description="Field path associated with the error (e.g., 'packages[0].targeting')"), ] = None - message: Annotated[str, Field(description='Human-readable error message')] + message: Annotated[str, Field(description="Human-readable error message")] retry_after: Annotated[ - float | None, Field(description='Seconds to wait before retrying the operation', ge=0.0) + float | None, Field(description="Seconds to wait before retrying the operation", ge=0.0) ] = None - suggestion: Annotated[str | None, Field(description='Suggested fix for the error')] = None + suggestion: Annotated[str | None, Field(description="Suggested fix for the error")] = None diff --git a/src/adcp/types/generated_poc/core/ext.py b/src/adcp/types/generated_poc/core/ext.py index 20b2ccc5..62607673 100644 --- a/src/adcp/types/generated_poc/core/ext.py +++ b/src/adcp/types/generated_poc/core/ext.py @@ -10,5 +10,5 @@ class ExtensionObject(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) diff --git a/src/adcp/types/generated_poc/core/format.py b/src/adcp/types/generated_poc/core/format.py index 6c52573c..078aec0e 100644 --- a/src/adcp/types/generated_poc/core/format.py +++ b/src/adcp/types/generated_poc/core/format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: core/format.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -17,7 +17,7 @@ class Assets(AdCPBaseModel): asset_id: Annotated[ str, Field( - description='Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object.' + description="Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object." ), ] asset_role: Annotated[ @@ -26,42 +26,42 @@ class Assets(AdCPBaseModel): description="Optional descriptive label for this asset's purpose (e.g., 'hero_image', 'logo', 'third_party_tracking'). Not used for referencing assets in manifests—use asset_id instead. This field is for human-readable documentation and UI display only." ), ] = None - asset_type: Annotated[asset_content_type.AssetContentType, Field(description='Type of asset')] + asset_type: Annotated[asset_content_type.AssetContentType, Field(description="Type of asset")] item_type: Annotated[ - Literal['individual'], - Field(description='Discriminator indicating this is an individual asset'), + Literal["individual"], + Field(description="Discriminator indicating this is an individual asset"), ] required: Annotated[ bool, Field( - description='Whether this asset is required (true) or optional (false). Required assets must be provided for a valid creative. Optional assets enhance the creative but are not mandatory.' + description="Whether this asset is required (true) or optional (false). Required assets must be provided for a valid creative. Optional assets enhance the creative but are not mandatory." ), ] requirements: Annotated[ dict[str, Any] | None, Field( - description='Technical requirements for this asset (dimensions, file size, duration, etc.). For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).' + description="Technical requirements for this asset (dimensions, file size, duration, etc.). For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms)." ), ] = None class Asset(AdCPBaseModel): - asset_id: Annotated[str, Field(description='Identifier for this asset within the group')] + asset_id: Annotated[str, Field(description="Identifier for this asset within the group")] asset_role: Annotated[ str | None, Field( description="Optional descriptive label for this asset's purpose. Not used for referencing assets in manifests—use asset_id instead. This field is for human-readable documentation and UI display only." ), ] = None - asset_type: Annotated[asset_content_type.AssetContentType, Field(description='Type of asset')] + asset_type: Annotated[asset_content_type.AssetContentType, Field(description="Type of asset")] required: Annotated[ bool, - Field(description='Whether this asset is required within each repetition of the group'), + Field(description="Whether this asset is required within each repetition of the group"), ] requirements: Annotated[ dict[str, Any] | None, Field( - description='Technical requirements for this asset. For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).' + description="Technical requirements for this asset. For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms)." ), ] = None @@ -70,23 +70,23 @@ class Assets1(AdCPBaseModel): asset_group_id: Annotated[ str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") ] - assets: Annotated[list[Asset], Field(description='Assets within each repetition of this group')] + assets: Annotated[list[Asset], Field(description="Assets within each repetition of this group")] item_type: Annotated[ - Literal['repeatable_group'], - Field(description='Discriminator indicating this is a repeatable asset group'), + Literal["repeatable_group"], + Field(description="Discriminator indicating this is a repeatable asset group"), ] - max_count: Annotated[int, Field(description='Maximum number of repetitions allowed', ge=1)] + max_count: Annotated[int, Field(description="Maximum number of repetitions allowed", ge=1)] min_count: Annotated[ int, Field( - description='Minimum number of repetitions required (if group is required) or allowed (if optional)', + description="Minimum number of repetitions required (if group is required) or allowed (if optional)", ge=0, ), ] required: Annotated[ bool, Field( - description='Whether this asset group is required. If true, at least min_count repetitions must be provided.' + description="Whether this asset group is required. If true, at least min_count repetitions must be provided." ), ] @@ -95,7 +95,7 @@ class AssetsRequired(AdCPBaseModel): asset_id: Annotated[ str, Field( - description='Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object.' + description="Unique identifier for this asset. Creative manifests MUST use this exact value as the key in the assets object." ), ] asset_role: Annotated[ @@ -104,36 +104,36 @@ class AssetsRequired(AdCPBaseModel): description="Optional descriptive label for this asset's purpose (e.g., 'hero_image', 'logo'). Not used for referencing assets in manifests—use asset_id instead. This field is for human-readable documentation and UI display only." ), ] = None - asset_type: Annotated[asset_content_type.AssetContentType, Field(description='Type of asset')] + asset_type: Annotated[asset_content_type.AssetContentType, Field(description="Type of asset")] item_type: Annotated[ - Literal['individual'], - Field(description='Discriminator indicating this is an individual asset requirement'), + Literal["individual"], + Field(description="Discriminator indicating this is an individual asset requirement"), ] - required: Annotated[bool | None, Field(description='Whether this asset is required')] = None + required: Annotated[bool | None, Field(description="Whether this asset is required")] = None requirements: Annotated[ dict[str, Any] | None, Field( - description='Technical requirements for this asset (dimensions, file size, duration, etc.). For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).' + description="Technical requirements for this asset (dimensions, file size, duration, etc.). For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms)." ), ] = None class Asset2(AdCPBaseModel): - asset_id: Annotated[str, Field(description='Identifier for this asset within the group')] + asset_id: Annotated[str, Field(description="Identifier for this asset within the group")] asset_role: Annotated[ str | None, Field( description="Optional descriptive label for this asset's purpose (e.g., 'hero_image', 'logo'). Not used for referencing assets in manifests—use asset_id instead. This field is for human-readable documentation and UI display only." ), ] = None - asset_type: Annotated[asset_content_type.AssetContentType, Field(description='Type of asset')] + asset_type: Annotated[asset_content_type.AssetContentType, Field(description="Type of asset")] required: Annotated[ - bool | None, Field(description='Whether this asset is required in each repetition') + bool | None, Field(description="Whether this asset is required in each repetition") ] = None requirements: Annotated[ dict[str, Any] | None, Field( - description='Technical requirements for this asset. For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms).' + description="Technical requirements for this asset. For template formats, use parameters_from_format_id: true to indicate asset parameters must match the format_id parameters (width/height/unit and/or duration_ms)." ), ] = None @@ -143,14 +143,14 @@ class AssetsRequired1(AdCPBaseModel): str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')") ] assets: Annotated[ - list[Asset2], Field(description='Assets within each repetition of this group') + list[Asset2], Field(description="Assets within each repetition of this group") ] item_type: Annotated[ - Literal['repeatable_group'], - Field(description='Discriminator indicating this is a repeatable asset group'), + Literal["repeatable_group"], + Field(description="Discriminator indicating this is a repeatable asset group"), ] - max_count: Annotated[int, Field(description='Maximum number of repetitions allowed', ge=1)] - min_count: Annotated[int, Field(description='Minimum number of repetitions required', ge=1)] + max_count: Annotated[int, Field(description="Maximum number of repetitions allowed", ge=1)] + min_count: Annotated[int, Field(description="Minimum number of repetitions required", ge=1)] class Responsive(AdCPBaseModel): @@ -163,36 +163,36 @@ class Dimensions(AdCPBaseModel): str | None, Field( description="Fixed aspect ratio constraint (e.g., '16:9', '4:3', '1:1')", - pattern='^\\d+:\\d+$', + pattern="^\\d+:\\d+$", ), ] = None - height: Annotated[int | None, Field(description='Fixed height in pixels', ge=1)] = None + height: Annotated[int | None, Field(description="Fixed height in pixels", ge=1)] = None max_height: Annotated[ - int | None, Field(description='Maximum height in pixels for responsive renders', ge=1) + int | None, Field(description="Maximum height in pixels for responsive renders", ge=1) ] = None max_width: Annotated[ - int | None, Field(description='Maximum width in pixels for responsive renders', ge=1) + int | None, Field(description="Maximum width in pixels for responsive renders", ge=1) ] = None min_height: Annotated[ - int | None, Field(description='Minimum height in pixels for responsive renders', ge=1) + int | None, Field(description="Minimum height in pixels for responsive renders", ge=1) ] = None min_width: Annotated[ - int | None, Field(description='Minimum width in pixels for responsive renders', ge=1) + int | None, Field(description="Minimum width in pixels for responsive renders", ge=1) ] = None responsive: Annotated[ - Responsive | None, Field(description='Indicates which dimensions are responsive/fluid') + Responsive | None, Field(description="Indicates which dimensions are responsive/fluid") ] = None - width: Annotated[int | None, Field(description='Fixed width in pixels', ge=1)] = None + width: Annotated[int | None, Field(description="Fixed width in pixels", ge=1)] = None class Renders(AdCPBaseModel): dimensions: Annotated[ - Dimensions, Field(description='Dimensions for this rendered piece (in pixels)') + Dimensions, Field(description="Dimensions for this rendered piece (in pixels)") ] parameters_from_format_id: Annotated[ bool | None, Field( - description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.' + description="When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly." ), ] = None role: Annotated[ @@ -203,17 +203,18 @@ class Renders(AdCPBaseModel): ] -Dimensions1 = Dimensions +class Dimensions1(Dimensions): + pass class Renders1(AdCPBaseModel): dimensions: Annotated[ - Dimensions1 | None, Field(description='Dimensions for this rendered piece (in pixels)') + Dimensions1 | None, Field(description="Dimensions for this rendered piece (in pixels)") ] = None parameters_from_format_id: Annotated[ Literal[True], Field( - description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.' + description="When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly." ), ] role: Annotated[ @@ -226,46 +227,46 @@ class Renders1(AdCPBaseModel): class FormatCard(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) format_id: Annotated[ format_id_1.FormatId, Field( - description='Creative format defining the card layout (typically format_card_standard)' + description="Creative format defining the card layout (typically format_card_standard)" ), ] manifest: Annotated[ dict[str, Any], - Field(description='Asset manifest for rendering the card, structure defined by the format'), + Field(description="Asset manifest for rendering the card, structure defined by the format"), ] class FormatCardDetailed(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) format_id: Annotated[ format_id_1.FormatId, Field( - description='Creative format defining the detailed card layout (typically format_card_detailed)' + description="Creative format defining the detailed card layout (typically format_card_detailed)" ), ] manifest: Annotated[ dict[str, Any], Field( - description='Asset manifest for rendering the detailed card, structure defined by the format' + description="Asset manifest for rendering the detailed card, structure defined by the format" ), ] class Format(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) accepts_parameters: Annotated[ list[format_id_parameter.FormatIdParameter] | None, Field( - description='List of parameters this format accepts in format_id. Template formats define which parameters (dimensions, duration, etc.) can be specified when instantiating the format. Empty or omitted means this is a concrete format with fixed parameters.' + description="List of parameters this format accepts in format_id. Template formats define which parameters (dimensions, duration, etc.) can be specified when instantiating the format. Empty or omitted means this is a concrete format with fixed parameters." ), ] = None assets: Annotated[ @@ -278,70 +279,70 @@ class Format(AdCPBaseModel): list[AssetsRequired | AssetsRequired1] | None, Field( deprecated=True, - description="DEPRECATED: Use 'assets' instead. Array of required assets or asset groups for this format. Each asset is identified by its asset_id, which must be used as the key in creative manifests. Can contain individual assets or repeatable asset sequences (e.g., carousel products, slideshow frames). This field is maintained for backward compatibility; new implementations should use 'assets' with the 'required' boolean on each asset." + description="DEPRECATED: Use 'assets' instead. Array of required assets or asset groups for this format. Each asset is identified by its asset_id, which must be used as the key in creative manifests. Can contain individual assets or repeatable asset sequences (e.g., carousel products, slideshow frames). This field is maintained for backward compatibility; new implementations should use 'assets' with the 'required' boolean on each asset.", ), ] = None delivery: Annotated[ dict[str, Any] | None, - Field(description='Delivery method specifications (e.g., hosted, VAST, third-party tags)'), + Field(description="Delivery method specifications (e.g., hosted, VAST, third-party tags)"), ] = None description: Annotated[ str | None, Field( - description='Plain text explanation of what this format does and what assets it requires' + description="Plain text explanation of what this format does and what assets it requires" ), ] = None example_url: Annotated[ AnyUrl | None, Field( - description='Optional URL to showcase page with examples and interactive demos of this format' + description="Optional URL to showcase page with examples and interactive demos of this format" ), ] = None format_card: Annotated[ FormatCard | None, Field( - description='Optional standard visual card (300x400px) for displaying this format in user interfaces. Can be rendered via preview_creative or pre-generated.' + description="Optional standard visual card (300x400px) for displaying this format in user interfaces. Can be rendered via preview_creative or pre-generated." ), ] = None format_card_detailed: Annotated[ FormatCardDetailed | None, Field( - description='Optional detailed card with carousel and full specifications. Provides rich format documentation similar to ad spec pages.' + description="Optional detailed card with carousel and full specifications. Provides rich format documentation similar to ad spec pages." ), ] = None format_id: Annotated[ format_id_1.FormatId, - Field(description='Structured format identifier with agent URL and format name'), + Field(description="Structured format identifier with agent URL and format name"), ] - name: Annotated[str, Field(description='Human-readable format name')] + name: Annotated[str, Field(description="Human-readable format name")] output_format_ids: Annotated[ list[format_id_1.FormatId] | None, Field( - description='For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand_manifest and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats).' + description="For generative formats: array of format IDs that this format can generate. When a format accepts inputs like brand_manifest and message, this specifies what concrete output formats can be produced (e.g., a generative banner format might output standard image banner formats)." ), ] = None preview_image: Annotated[ AnyUrl | None, Field( - description='DEPRECATED: Use format_card instead. Optional preview image URL for format browsing/discovery UI. Should be 400x300px (4:3 aspect ratio) PNG or JPG. Used as thumbnail/card image in format browsers. This field is maintained for backward compatibility but format_card provides a more flexible, structured approach.' + description="DEPRECATED: Use format_card instead. Optional preview image URL for format browsing/discovery UI. Should be 400x300px (4:3 aspect ratio) PNG or JPG. Used as thumbnail/card image in format browsers. This field is maintained for backward compatibility but format_card provides a more flexible, structured approach." ), ] = None renders: Annotated[ list[Renders | Renders1] | None, Field( - description='Specification of rendered pieces for this format. Most formats produce a single render. Companion ad formats (video + banner), adaptive formats, and multi-placement formats produce multiple renders. Each render specifies its role and dimensions.', + description="Specification of rendered pieces for this format. Most formats produce a single render. Companion ad formats (video + banner), adaptive formats, and multi-placement formats produce multiple renders. Each render specifies its role and dimensions.", min_length=1, ), ] = None supported_macros: Annotated[ list[str] | None, Field( - description='List of universal macros supported by this format (e.g., MEDIA_BUY_ID, CACHEBUSTER, DEVICE_ID). Used for validation and developer tooling.' + description="List of universal macros supported by this format (e.g., MEDIA_BUY_ID, CACHEBUSTER, DEVICE_ID). Used for validation and developer tooling." ), ] = None type: Annotated[ format_category.FormatCategory, Field( - description='Media type of this format - determines rendering method and asset requirements' + description="Media type of this format - determines rendering method and asset requirements" ), ] diff --git a/src/adcp/types/generated_poc/core/format_id.py b/src/adcp/types/generated_poc/core/format_id.py index d38bda83..99d93f83 100644 --- a/src/adcp/types/generated_poc/core/format_id.py +++ b/src/adcp/types/generated_poc/core/format_id.py @@ -12,7 +12,7 @@ class FormatId(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) agent_url: Annotated[ AnyUrl, @@ -23,14 +23,14 @@ class FormatId(AdCPBaseModel): duration_ms: Annotated[ float | None, Field( - description='Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.', + description="Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.", ge=1.0, ), ] = None height: Annotated[ int | None, Field( - description='Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.', + description="Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.", ge=1, ), ] = None @@ -38,13 +38,13 @@ class FormatId(AdCPBaseModel): str, Field( description="Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.", - pattern='^[a-zA-Z0-9_-]+$', + pattern="^[a-zA-Z0-9_-]+$", ), ] width: Annotated[ int | None, Field( - description='Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.', + description="Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.", ge=1, ), ] = None diff --git a/src/adcp/types/generated_poc/core/frequency_cap.py b/src/adcp/types/generated_poc/core/frequency_cap.py index 02d931f1..1b033db6 100644 --- a/src/adcp/types/generated_poc/core/frequency_cap.py +++ b/src/adcp/types/generated_poc/core/frequency_cap.py @@ -12,8 +12,8 @@ class FrequencyCap(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) suppress_minutes: Annotated[ - float, Field(description='Minutes to suppress after impression', ge=0.0) + float, Field(description="Minutes to suppress after impression", ge=0.0) ] diff --git a/src/adcp/types/generated_poc/core/identifier.py b/src/adcp/types/generated_poc/core/identifier.py new file mode 100644 index 00000000..9b950706 --- /dev/null +++ b/src/adcp/types/generated_poc/core/identifier.py @@ -0,0 +1,27 @@ +# generated by datamodel-codegen: +# filename: core/identifier.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..enums import identifier_types + + +class Identifier(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + type: Annotated[ + identifier_types.PropertyIdentifierTypes, Field(description="Type of identifier") + ] + value: Annotated[ + str, + Field( + description="The identifier value. For domain type: 'example.com' matches base domain plus www and m subdomains; 'edition.example.com' matches that specific subdomain; '*.example.com' matches ALL subdomains but NOT base domain" + ), + ] diff --git a/src/adcp/types/generated_poc/core/mcp_webhook_payload.py b/src/adcp/types/generated_poc/core/mcp_webhook_payload.py index 986f348f..89670219 100644 --- a/src/adcp/types/generated_poc/core/mcp_webhook_payload.py +++ b/src/adcp/types/generated_poc/core/mcp_webhook_payload.py @@ -16,56 +16,56 @@ class McpWebhookPayload(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context_id: Annotated[ str | None, Field( - description='Session/conversation identifier. Use this to continue the conversation if input-required status needs clarification or additional parameters.' + description="Session/conversation identifier. Use this to continue the conversation if input-required status needs clarification or additional parameters." ), ] = None domain: Annotated[ adcp_domain.AdcpDomain | None, Field( - description='AdCP domain this task belongs to. Helps classify the operation type at a high level.' + description="AdCP domain this task belongs to. Helps classify the operation type at a high level." ), ] = None message: Annotated[ str | None, Field( - description='Human-readable summary of the current task state. Provides context about what happened and what action may be needed.' + description="Human-readable summary of the current task state. Provides context about what happened and what action may be needed." ), ] = None operation_id: Annotated[ str | None, Field( - description='Publisher-defined operation identifier correlating a sequence of task updates across webhooks.' + description="Publisher-defined operation identifier correlating a sequence of task updates across webhooks." ), ] = None result: Annotated[ async_response_data.AdcpAsyncResponseData | None, Field( - description='Task-specific payload matching the status. For completed/failed, contains the full task response. For working/input-required/submitted, contains status-specific data. This is the data layer that AdCP specs - same structure used in A2A status.message.parts[].data.' + description="Task-specific payload matching the status. For completed/failed, contains the full task response. For working/input-required/submitted, contains status-specific data. This is the data layer that AdCP specs - same structure used in A2A status.message.parts[].data." ), ] = None status: Annotated[ task_status.TaskStatus, Field( - description='Current task status. Webhooks are triggered for status changes after initial submission.' + description="Current task status. Webhooks are triggered for status changes after initial submission." ), ] task_id: Annotated[ str, Field( - description='Unique identifier for this task. Use this to correlate webhook notifications with the original task submission.' + description="Unique identifier for this task. Use this to correlate webhook notifications with the original task submission." ), ] task_type: Annotated[ task_type_1.TaskType, Field( - description='Type of AdCP operation that triggered this webhook. Enables webhook handlers to route to appropriate processing logic.' + description="Type of AdCP operation that triggered this webhook. Enables webhook handlers to route to appropriate processing logic." ), ] timestamp: Annotated[ - AwareDatetime, Field(description='ISO 8601 timestamp when this webhook was generated.') + AwareDatetime, Field(description="ISO 8601 timestamp when this webhook was generated.") ] diff --git a/src/adcp/types/generated_poc/core/measurement.py b/src/adcp/types/generated_poc/core/measurement.py index a45cc8e0..4188b781 100644 --- a/src/adcp/types/generated_poc/core/measurement.py +++ b/src/adcp/types/generated_poc/core/measurement.py @@ -12,29 +12,29 @@ class Measurement(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) attribution: Annotated[ str, Field( - description='Attribution methodology', - examples=['deterministic_purchase', 'probabilistic'], + description="Attribution methodology", + examples=["deterministic_purchase", "probabilistic"], ), ] reporting: Annotated[ str, Field( - description='Reporting frequency and format', - examples=['weekly_dashboard', 'real_time_api'], + description="Reporting frequency and format", + examples=["weekly_dashboard", "real_time_api"], ), ] type: Annotated[ str, Field( - description='Type of measurement', - examples=['incremental_sales_lift', 'brand_lift', 'foot_traffic'], + description="Type of measurement", + examples=["incremental_sales_lift", "brand_lift", "foot_traffic"], ), ] window: Annotated[ - str | None, Field(description='Attribution window', examples=['30_days', '7_days']) + str | None, Field(description="Attribution window", examples=["30_days", "7_days"]) ] = None diff --git a/src/adcp/types/generated_poc/core/media_buy.py b/src/adcp/types/generated_poc/core/media_buy.py index 1697ef17..8fa3f281 100644 --- a/src/adcp/types/generated_poc/core/media_buy.py +++ b/src/adcp/types/generated_poc/core/media_buy.py @@ -16,25 +16,25 @@ class MediaBuy(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[ str | None, Field(description="Buyer's reference identifier for this media buy") ] = None - created_at: Annotated[AwareDatetime | None, Field(description='Creation timestamp')] = None + created_at: Annotated[AwareDatetime | None, Field(description="Creation timestamp")] = None creative_deadline: Annotated[ - AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline') + AwareDatetime | None, Field(description="ISO 8601 timestamp for creative upload deadline") ] = None ext: ext_1.ExtensionObject | None = None media_buy_id: Annotated[ str, Field(description="Publisher's unique identifier for the media buy") ] packages: Annotated[ - list[package.Package], Field(description='Array of packages within this media buy') + list[package.Package], Field(description="Array of packages within this media buy") ] promoted_offering: Annotated[ - str, Field(description='Description of advertiser and what is being promoted') + str, Field(description="Description of advertiser and what is being promoted") ] status: media_buy_status.MediaBuyStatus - total_budget: Annotated[float, Field(description='Total budget amount', ge=0.0)] - updated_at: Annotated[AwareDatetime | None, Field(description='Last update timestamp')] = None + total_budget: Annotated[float, Field(description="Total budget amount", ge=0.0)] + updated_at: Annotated[AwareDatetime | None, Field(description="Last update timestamp")] = None diff --git a/src/adcp/types/generated_poc/core/package.py b/src/adcp/types/generated_poc/core/package.py index 658e4c34..397d1ee2 100644 --- a/src/adcp/types/generated_poc/core/package.py +++ b/src/adcp/types/generated_poc/core/package.py @@ -17,19 +17,19 @@ class Package(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bid_price: Annotated[ float | None, Field( - description='Bid price for auction-based CPM pricing (present if using cpm-auction-option)', + description="Bid price for auction-based CPM pricing (present if using cpm-auction-option)", ge=0.0, ), ] = None budget: Annotated[ float | None, Field( - description='Budget allocation for this package in the currency specified by the pricing option', + description="Budget allocation for this package in the currency specified by the pricing option", ge=0.0, ), ] = None @@ -38,22 +38,22 @@ class Package(AdCPBaseModel): ] = None creative_assignments: Annotated[ list[creative_assignment.CreativeAssignment] | None, - Field(description='Creative assets assigned to this package'), + Field(description="Creative assets assigned to this package"), ] = None ext: ext_1.ExtensionObject | None = None format_ids_to_provide: Annotated[ list[format_id.FormatId] | None, - Field(description='Format IDs that creative assets will be provided for this package'), + Field(description="Format IDs that creative assets will be provided for this package"), ] = None impressions: Annotated[ - float | None, Field(description='Impression goal for this package', ge=0.0) + float | None, Field(description="Impression goal for this package", ge=0.0) ] = None pacing: pacing_1.Pacing | None = None package_id: Annotated[str, Field(description="Publisher's unique identifier for the package")] paused: Annotated[ bool | None, Field( - description='Whether this package is paused by the buyer. Paused packages do not deliver impressions. Defaults to false.' + description="Whether this package is paused by the buyer. Paused packages do not deliver impressions. Defaults to false." ), ] = False pricing_option_id: Annotated[ @@ -63,6 +63,6 @@ class Package(AdCPBaseModel): ), ] = None product_id: Annotated[ - str | None, Field(description='ID of the product this package is based on') + str | None, Field(description="ID of the product this package is based on") ] = None targeting_overlay: targeting.TargetingOverlay | None = None diff --git a/src/adcp/types/generated_poc/core/performance_feedback.py b/src/adcp/types/generated_poc/core/performance_feedback.py index 0dbcd29e..d2630b80 100644 --- a/src/adcp/types/generated_poc/core/performance_feedback.py +++ b/src/adcp/types/generated_poc/core/performance_feedback.py @@ -16,63 +16,63 @@ class MeasurementPeriod(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) end: Annotated[ - AwareDatetime, Field(description='ISO 8601 end timestamp for measurement period') + AwareDatetime, Field(description="ISO 8601 end timestamp for measurement period") ] start: Annotated[ - AwareDatetime, Field(description='ISO 8601 start timestamp for measurement period') + AwareDatetime, Field(description="ISO 8601 start timestamp for measurement period") ] class Status(Enum): - accepted = 'accepted' - queued = 'queued' - applied = 'applied' - rejected = 'rejected' + accepted = "accepted" + queued = "queued" + applied = "applied" + rejected = "rejected" class PerformanceFeedback(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) applied_at: Annotated[ AwareDatetime | None, Field( - description='ISO 8601 timestamp when feedback was applied to optimization algorithms' + description="ISO 8601 timestamp when feedback was applied to optimization algorithms" ), ] = None creative_id: Annotated[ - str | None, Field(description='Specific creative asset (if feedback is creative-specific)') + str | None, Field(description="Specific creative asset (if feedback is creative-specific)") ] = None feedback_id: Annotated[ - str, Field(description='Unique identifier for this performance feedback submission') + str, Field(description="Unique identifier for this performance feedback submission") ] feedback_source: Annotated[ - feedback_source_1.FeedbackSource, Field(description='Source of the performance data') + feedback_source_1.FeedbackSource, Field(description="Source of the performance data") ] measurement_period: Annotated[ - MeasurementPeriod, Field(description='Time period for performance measurement') + MeasurementPeriod, Field(description="Time period for performance measurement") ] media_buy_id: Annotated[str, Field(description="Publisher's media buy identifier")] metric_type: Annotated[ - metric_type_1.MetricType, Field(description='The business metric being measured') + metric_type_1.MetricType, Field(description="The business metric being measured") ] package_id: Annotated[ str | None, Field( - description='Specific package within the media buy (if feedback is package-specific)' + description="Specific package within the media buy (if feedback is package-specific)" ), ] = None performance_index: Annotated[ float, Field( - description='Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)', + description="Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)", ge=0.0, ), ] - status: Annotated[Status, Field(description='Processing status of the performance feedback')] + status: Annotated[Status, Field(description="Processing status of the performance feedback")] submitted_at: Annotated[ - AwareDatetime, Field(description='ISO 8601 timestamp when feedback was submitted') + AwareDatetime, Field(description="ISO 8601 timestamp when feedback was submitted") ] diff --git a/src/adcp/types/generated_poc/core/placement.py b/src/adcp/types/generated_poc/core/placement.py index 76add5bb..5d905f45 100644 --- a/src/adcp/types/generated_poc/core/placement.py +++ b/src/adcp/types/generated_poc/core/placement.py @@ -14,15 +14,15 @@ class Placement(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) description: Annotated[ - str | None, Field(description='Detailed description of where and how the placement appears') + str | None, Field(description="Detailed description of where and how the placement appears") ] = None format_ids: Annotated[ list[format_id.FormatId] | None, Field( - description='Format IDs supported by this specific placement. Can include: (1) concrete format_ids (fixed dimensions), (2) template format_ids without parameters (accepts any dimensions/duration), or (3) parameterized format_ids (specific dimension/duration constraints).', + description="Format IDs supported by this specific placement. Can include: (1) concrete format_ids (fixed dimensions), (2) template format_ids without parameters (accepts any dimensions/duration), or (3) parameterized format_ids (specific dimension/duration constraints).", min_length=1, ), ] = None @@ -33,5 +33,5 @@ class Placement(AdCPBaseModel): ), ] placement_id: Annotated[ - str, Field(description='Unique identifier for the placement within the product') + str, Field(description="Unique identifier for the placement within the product") ] diff --git a/src/adcp/types/generated_poc/core/pricing_option.py b/src/adcp/types/generated_poc/core/pricing_option.py index 2af906a5..37fb85b2 100644 --- a/src/adcp/types/generated_poc/core/pricing_option.py +++ b/src/adcp/types/generated_poc/core/pricing_option.py @@ -45,7 +45,7 @@ class PricingOption( | cpp_option.CppPricingOption | flat_rate_option.FlatRatePricingOption, Field( - description='A pricing model option offered by a publisher for a product. Each pricing model has its own schema with model-specific requirements.', - title='Pricing Option', + description="A pricing model option offered by a publisher for a product. Each pricing model has its own schema with model-specific requirements.", + title="Pricing Option", ), ] diff --git a/src/adcp/types/generated_poc/core/product.py b/src/adcp/types/generated_poc/core/product.py index c89a0558..adc5576b 100644 --- a/src/adcp/types/generated_poc/core/product.py +++ b/src/adcp/types/generated_poc/core/product.py @@ -35,100 +35,100 @@ class DeliveryMeasurement(AdCPBaseModel): class ProductCard(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) format_id: Annotated[ format_id_1.FormatId, Field( - description='Creative format defining the card layout (typically product_card_standard)' + description="Creative format defining the card layout (typically product_card_standard)" ), ] manifest: Annotated[ dict[str, Any], - Field(description='Asset manifest for rendering the card, structure defined by the format'), + Field(description="Asset manifest for rendering the card, structure defined by the format"), ] class ProductCardDetailed(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) format_id: Annotated[ format_id_1.FormatId, Field( - description='Creative format defining the detailed card layout (typically product_card_detailed)' + description="Creative format defining the detailed card layout (typically product_card_detailed)" ), ] manifest: Annotated[ dict[str, Any], Field( - description='Asset manifest for rendering the detailed card, structure defined by the format' + description="Asset manifest for rendering the detailed card, structure defined by the format" ), ] class Product(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) brief_relevance: Annotated[ str | None, Field( - description='Explanation of why this product matches the brief (only included when brief is provided)' + description="Explanation of why this product matches the brief (only included when brief is provided)" ), ] = None creative_policy: creative_policy_1.CreativePolicy | None = None delivery_measurement: Annotated[ DeliveryMeasurement, Field( - description='Measurement provider and methodology for delivery metrics. The buyer accepts the declared provider as the source of truth for the buy. REQUIRED for all products.' + description="Measurement provider and methodology for delivery metrics. The buyer accepts the declared provider as the source of truth for the buy. REQUIRED for all products." ), ] delivery_type: delivery_type_1.DeliveryType description: Annotated[ - str, Field(description='Detailed description of the product and its inventory') + str, Field(description="Detailed description of the product and its inventory") ] estimated_exposures: Annotated[ int | None, - Field(description='Estimated exposures/impressions for guaranteed products', ge=0), + Field(description="Estimated exposures/impressions for guaranteed products", ge=0), ] = None expires_at: Annotated[ - AwareDatetime | None, Field(description='Expiration timestamp for custom products') + AwareDatetime | None, Field(description="Expiration timestamp for custom products") ] = None ext: ext_1.ExtensionObject | None = None format_ids: Annotated[ list[format_id_1.FormatId], Field( - description='Array of supported creative format IDs - structured format_id objects with agent_url and id' + description="Array of supported creative format IDs - structured format_id objects with agent_url and id" ), ] - is_custom: Annotated[bool | None, Field(description='Whether this is a custom product')] = None + is_custom: Annotated[bool | None, Field(description="Whether this is a custom product")] = None measurement: measurement_1.Measurement | None = None - name: Annotated[str, Field(description='Human-readable product name')] + name: Annotated[str, Field(description="Human-readable product name")] placements: Annotated[ list[placement.Placement] | None, Field( - description='Optional array of specific placements within this product. When provided, buyers can target specific placements when assigning creatives.', + description="Optional array of specific placements within this product. When provided, buyers can target specific placements when assigning creatives.", min_length=1, ), ] = None pricing_options: Annotated[ list[pricing_option.PricingOption], - Field(description='Available pricing models for this product', min_length=1), + Field(description="Available pricing models for this product", min_length=1), ] product_card: Annotated[ ProductCard | None, Field( - description='Optional standard visual card (300x400px) for displaying this product in user interfaces. Can be rendered via preview_creative or pre-generated.' + description="Optional standard visual card (300x400px) for displaying this product in user interfaces. Can be rendered via preview_creative or pre-generated." ), ] = None product_card_detailed: Annotated[ ProductCardDetailed | None, Field( - description='Optional detailed card with carousel and full specifications. Provides rich product presentation similar to media kit pages.' + description="Optional detailed card with carousel and full specifications. Provides rich product presentation similar to media kit pages." ), ] = None - product_id: Annotated[str, Field(description='Unique identifier for the product')] + product_id: Annotated[str, Field(description="Unique identifier for the product")] publisher_properties: Annotated[ list[publisher_property_selector.PublisherPropertySelector], Field( diff --git a/src/adcp/types/generated_poc/core/product_filters.py b/src/adcp/types/generated_poc/core/product_filters.py index b63f935c..27168ed5 100644 --- a/src/adcp/types/generated_poc/core/product_filters.py +++ b/src/adcp/types/generated_poc/core/product_filters.py @@ -18,43 +18,43 @@ class BudgetRange(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern='^[A-Z]{3}$' + description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern="^[A-Z]{3}$" ), ] - max: Annotated[float | None, Field(description='Maximum budget amount', ge=0.0)] = None - min: Annotated[float, Field(description='Minimum budget amount', ge=0.0)] + max: Annotated[float | None, Field(description="Maximum budget amount", ge=0.0)] = None + min: Annotated[float, Field(description="Minimum budget amount", ge=0.0)] class BudgetRange1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern='^[A-Z]{3}$' + description="ISO 4217 currency code (e.g., 'USD', 'EUR', 'GBP')", pattern="^[A-Z]{3}$" ), ] - max: Annotated[float, Field(description='Maximum budget amount', ge=0.0)] - min: Annotated[float | None, Field(description='Minimum budget amount', ge=0.0)] = None + max: Annotated[float, Field(description="Maximum budget amount", ge=0.0)] + min: Annotated[float | None, Field(description="Minimum budget amount", ge=0.0)] = None class Country(RootModel[str]): - root: Annotated[str, Field(pattern='^[A-Z]{2}$')] + root: Annotated[str, Field(pattern="^[A-Z]{2}$")] class ProductFilters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) budget_range: Annotated[ BudgetRange | BudgetRange1 | None, - Field(description='Budget range to filter appropriate products'), + Field(description="Budget range to filter appropriate products"), ] = None channels: Annotated[ list[channels_1.AdvertisingChannels] | None, @@ -70,28 +70,28 @@ class ProductFilters(AdCPBaseModel): end_date: Annotated[ date | None, Field( - description='Campaign end date (ISO 8601 date format: YYYY-MM-DD) for availability checks' + description="Campaign end date (ISO 8601 date format: YYYY-MM-DD) for availability checks" ), ] = None format_ids: Annotated[ - list[format_id.FormatId] | None, Field(description='Filter by specific format IDs') + list[format_id.FormatId] | None, Field(description="Filter by specific format IDs") ] = None format_types: Annotated[ - list[format_category.FormatCategory] | None, Field(description='Filter by format types') + list[format_category.FormatCategory] | None, Field(description="Filter by format types") ] = None is_fixed_price: Annotated[ - bool | None, Field(description='Filter for fixed price vs auction products') + bool | None, Field(description="Filter for fixed price vs auction products") ] = None min_exposures: Annotated[ int | None, - Field(description='Minimum exposures/impressions needed for measurement validity', ge=1), + Field(description="Minimum exposures/impressions needed for measurement validity", ge=1), ] = None standard_formats_only: Annotated[ - bool | None, Field(description='Only return products accepting IAB standard formats') + bool | None, Field(description="Only return products accepting IAB standard formats") ] = None start_date: Annotated[ date | None, Field( - description='Campaign start date (ISO 8601 date format: YYYY-MM-DD) for availability checks' + description="Campaign start date (ISO 8601 date format: YYYY-MM-DD) for availability checks" ), ] = None diff --git a/src/adcp/types/generated_poc/core/promoted_offerings.py b/src/adcp/types/generated_poc/core/promoted_offerings.py index ba031503..acf4f68d 100644 --- a/src/adcp/types/generated_poc/core/promoted_offerings.py +++ b/src/adcp/types/generated_poc/core/promoted_offerings.py @@ -14,28 +14,28 @@ class AssetType(Enum): - image = 'image' - video = 'video' - audio = 'audio' - vast = 'vast' - daast = 'daast' - text = 'text' - url = 'url' - html = 'html' - css = 'css' - javascript = 'javascript' - webhook = 'webhook' + image = "image" + video = "video" + audio = "audio" + vast = "vast" + daast = "daast" + text = "text" + url = "url" + html = "html" + css = "css" + javascript = "javascript" + webhook = "webhook" class AssetSelectors(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_types: Annotated[ list[AssetType] | None, Field(description="Filter by asset type (e.g., ['image', 'video'])") ] = None exclude_tags: Annotated[ - list[str] | None, Field(description='Exclude assets with these tags') + list[str] | None, Field(description="Exclude assets with these tags") ] = None tags: Annotated[ list[str] | None, @@ -45,10 +45,10 @@ class AssetSelectors(AdCPBaseModel): class Offering(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assets: Annotated[ - list[dict[str, Any]] | None, Field(description='Assets specific to this offering') + list[dict[str, Any]] | None, Field(description="Assets specific to this offering") ] = None description: Annotated[str | None, Field(description="Description of what's being offered")] = ( None @@ -60,27 +60,27 @@ class Offering(AdCPBaseModel): class PromotedOfferings(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_selectors: Annotated[ AssetSelectors | None, - Field(description='Selectors to choose specific assets from the brand manifest'), + Field(description="Selectors to choose specific assets from the brand manifest"), ] = None brand_manifest: Annotated[ brand_manifest_ref.BrandManifestReference, Field( - description='Brand information manifest containing assets, themes, and guidelines. Can be provided inline or as a URL reference to a hosted manifest.' + description="Brand information manifest containing assets, themes, and guidelines. Can be provided inline or as a URL reference to a hosted manifest." ), ] offerings: Annotated[ list[Offering] | None, Field( - description='Inline offerings for campaigns without a product catalog. Each offering has a name, description, and associated assets.' + description="Inline offerings for campaigns without a product catalog. Each offering has a name, description, and associated assets." ), ] = None product_selectors: Annotated[ promoted_products.PromotedProducts | None, Field( - description='Selectors to choose which products/offerings from the brand manifest product catalog to promote' + description="Selectors to choose which products/offerings from the brand manifest product catalog to promote" ), ] = None diff --git a/src/adcp/types/generated_poc/core/promoted_products.py b/src/adcp/types/generated_poc/core/promoted_products.py index b3fa8d01..c24e5e76 100644 --- a/src/adcp/types/generated_poc/core/promoted_products.py +++ b/src/adcp/types/generated_poc/core/promoted_products.py @@ -12,7 +12,7 @@ class PromotedProducts(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) manifest_category: Annotated[ str | None, @@ -28,7 +28,7 @@ class PromotedProducts(AdCPBaseModel): ] = None manifest_skus: Annotated[ list[str] | None, - Field(description='Direct product SKU references from the brand manifest product catalog'), + Field(description="Direct product SKU references from the brand manifest product catalog"), ] = None manifest_tags: Annotated[ list[str] | None, diff --git a/src/adcp/types/generated_poc/core/property.py b/src/adcp/types/generated_poc/core/property.py index deb01cf5..5eea8a14 100644 --- a/src/adcp/types/generated_poc/core/property.py +++ b/src/adcp/types/generated_poc/core/property.py @@ -17,11 +17,11 @@ class Identifier(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) type: Annotated[ identifier_types.PropertyIdentifierTypes, - Field(description='Type of identifier for this property'), + Field(description="Type of identifier for this property"), ] value: Annotated[ str, @@ -33,30 +33,30 @@ class Identifier(AdCPBaseModel): class Property(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) identifiers: Annotated[ - list[Identifier], Field(description='Array of identifiers for this property', min_length=1) + list[Identifier], Field(description="Array of identifiers for this property", min_length=1) ] - name: Annotated[str, Field(description='Human-readable property name')] + name: Annotated[str, Field(description="Human-readable property name")] property_id: Annotated[ property_id_1.PropertyId | None, Field( - description='Unique identifier for this property (optional). Enables referencing properties by ID instead of repeating full objects.' + description="Unique identifier for this property (optional). Enables referencing properties by ID instead of repeating full objects." ), ] = None property_type: Annotated[ - property_type_1.PropertyType, Field(description='Type of advertising property') + property_type_1.PropertyType, Field(description="Type of advertising property") ] publisher_domain: Annotated[ str | None, Field( - description='Domain where adagents.json should be checked for authorization validation. Required for list_authorized_properties response. Optional in adagents.json (file location implies domain).' + description="Domain where adagents.json should be checked for authorization validation. Required for list_authorized_properties response. Optional in adagents.json (file location implies domain)." ), ] = None tags: Annotated[ list[property_tag.PropertyTag] | None, Field( - description='Tags for categorization and grouping (e.g., network membership, content categories)' + description="Tags for categorization and grouping (e.g., network membership, content categories)" ), ] = None diff --git a/src/adcp/types/generated_poc/core/property_id.py b/src/adcp/types/generated_poc/core/property_id.py index e5c07492..d282b8e6 100644 --- a/src/adcp/types/generated_poc/core/property_id.py +++ b/src/adcp/types/generated_poc/core/property_id.py @@ -13,9 +13,9 @@ class PropertyId(RootModel[str]): root: Annotated[ str, Field( - description='Identifier for a publisher property. Must be lowercase alphanumeric with underscores only.', - examples=['cnn_ctv_app', 'homepage', 'mobile_ios', 'instagram'], - pattern='^[a-z0-9_]+$', - title='Property ID', + description="Identifier for a publisher property. Must be lowercase alphanumeric with underscores only.", + examples=["cnn_ctv_app", "homepage", "mobile_ios", "instagram"], + pattern="^[a-z0-9_]+$", + title="Property ID", ), ] diff --git a/src/adcp/types/generated_poc/core/property_list_ref.py b/src/adcp/types/generated_poc/core/property_list_ref.py new file mode 100644 index 00000000..0bf08373 --- /dev/null +++ b/src/adcp/types/generated_poc/core/property_list_ref.py @@ -0,0 +1,26 @@ +# generated by datamodel-codegen: +# filename: core/property_list_ref.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, ConfigDict, Field + + +class PropertyListReference(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + agent_url: Annotated[AnyUrl, Field(description="URL of the agent managing the property list")] + auth_token: Annotated[ + str | None, + Field( + description="JWT or other authorization token for accessing the list. Optional if the list is public or caller has implicit access." + ), + ] = None + list_id: Annotated[ + str, Field(description="Identifier for the property list within the agent", min_length=1) + ] diff --git a/src/adcp/types/generated_poc/core/property_tag.py b/src/adcp/types/generated_poc/core/property_tag.py index 9f3fc213..f681eaa1 100644 --- a/src/adcp/types/generated_poc/core/property_tag.py +++ b/src/adcp/types/generated_poc/core/property_tag.py @@ -13,9 +13,9 @@ class PropertyTag(RootModel[str]): root: Annotated[ str, Field( - description='Tag for categorizing publisher properties. Must be lowercase alphanumeric with underscores only.', - examples=['ctv', 'premium', 'news', 'sports', 'meta_network', 'social_media'], - pattern='^[a-z0-9_]+$', - title='Property Tag', + description="Tag for categorizing publisher properties. Must be lowercase alphanumeric with underscores only.", + examples=["ctv", "premium", "news", "sports", "meta_network", "social_media"], + pattern="^[a-z0-9_]+$", + title="Property Tag", ), ] diff --git a/src/adcp/types/generated_poc/core/protocol_envelope.py b/src/adcp/types/generated_poc/core/protocol_envelope.py index c32caac7..f272f199 100644 --- a/src/adcp/types/generated_poc/core/protocol_envelope.py +++ b/src/adcp/types/generated_poc/core/protocol_envelope.py @@ -15,47 +15,47 @@ class ProtocolEnvelope(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context_id: Annotated[ str | None, Field( - description='Session/conversation identifier for tracking related operations across multiple task invocations. Managed by the protocol layer to maintain conversational context.' + description="Session/conversation identifier for tracking related operations across multiple task invocations. Managed by the protocol layer to maintain conversational context." ), ] = None message: Annotated[ str | None, Field( - description='Human-readable summary of the task result. Provides natural language explanation of what happened, suitable for display to end users or for AI agent comprehension. Generated by the protocol layer based on the task response.' + description="Human-readable summary of the task result. Provides natural language explanation of what happened, suitable for display to end users or for AI agent comprehension. Generated by the protocol layer based on the task response." ), ] = None payload: Annotated[ dict[str, Any], Field( - description='The actual task-specific response data. This is the content defined in individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json). Contains only domain-specific data without protocol-level fields.' + description="The actual task-specific response data. This is the content defined in individual task response schemas (e.g., get-products-response.json, create-media-buy-response.json). Contains only domain-specific data without protocol-level fields." ), ] push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( - description='Push notification configuration for async task updates (A2A and REST protocols). Echoed from the request to confirm webhook settings. Specifies URL, authentication scheme (Bearer or HMAC-SHA256), and credentials. MCP uses progress notifications instead of webhooks.' + description="Push notification configuration for async task updates (A2A and REST protocols). Echoed from the request to confirm webhook settings. Specifies URL, authentication scheme (Bearer or HMAC-SHA256), and credentials. MCP uses progress notifications instead of webhooks." ), ] = None status: Annotated[ task_status.TaskStatus, Field( - description='Current task execution state. Indicates whether the task is completed, in progress (working), submitted for async processing, failed, or requires user input. Managed by the protocol layer.' + description="Current task execution state. Indicates whether the task is completed, in progress (working), submitted for async processing, failed, or requires user input. Managed by the protocol layer." ), ] task_id: Annotated[ str | None, Field( - description='Unique identifier for tracking asynchronous operations. Present when a task requires extended processing time. Used to query task status and retrieve results when complete.' + description="Unique identifier for tracking asynchronous operations. Present when a task requires extended processing time. Used to query task status and retrieve results when complete." ), ] = None timestamp: Annotated[ AwareDatetime | None, Field( - description='ISO 8601 timestamp when the response was generated. Useful for debugging, logging, cache validation, and tracking async operation progress.' + description="ISO 8601 timestamp when the response was generated. Useful for debugging, logging, cache validation, and tracking async operation progress." ), ] = None diff --git a/src/adcp/types/generated_poc/core/publisher_property_selector.py b/src/adcp/types/generated_poc/core/publisher_property_selector.py index ce36f8bb..7644a672 100644 --- a/src/adcp/types/generated_poc/core/publisher_property_selector.py +++ b/src/adcp/types/generated_poc/core/publisher_property_selector.py @@ -14,26 +14,26 @@ class PublisherPropertySelector1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) publisher_domain: Annotated[ str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] selection_type: Annotated[ - Literal['all'], + Literal["all"], Field( - description='Discriminator indicating all properties from this publisher are included' + description="Discriminator indicating all properties from this publisher are included" ), ] class PublisherPropertySelector2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) property_ids: Annotated[ list[property_id.PropertyId], @@ -43,18 +43,18 @@ class PublisherPropertySelector2(AdCPBaseModel): str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] selection_type: Annotated[ - Literal['by_id'], - Field(description='Discriminator indicating selection by specific property IDs'), + Literal["by_id"], + Field(description="Discriminator indicating selection by specific property IDs"), ] class PublisherPropertySelector3(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) property_tags: Annotated[ list[property_tag.PropertyTag], @@ -67,11 +67,11 @@ class PublisherPropertySelector3(AdCPBaseModel): str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] selection_type: Annotated[ - Literal['by_tag'], Field(description='Discriminator indicating selection by property tags') + Literal["by_tag"], Field(description="Discriminator indicating selection by property tags") ] @@ -82,7 +82,7 @@ class PublisherPropertySelector( PublisherPropertySelector1 | PublisherPropertySelector2 | PublisherPropertySelector3, Field( description="Selects properties from a publisher's adagents.json. Used for both product definitions and agent authorization. Supports three selection patterns: all properties, specific IDs, or by tags.", - discriminator='selection_type', - title='Publisher Property Selector', + discriminator="selection_type", + title="Publisher Property Selector", ), ] diff --git a/src/adcp/types/generated_poc/core/push_notification_config.py b/src/adcp/types/generated_poc/core/push_notification_config.py index 150ff343..950afb9b 100644 --- a/src/adcp/types/generated_poc/core/push_notification_config.py +++ b/src/adcp/types/generated_poc/core/push_notification_config.py @@ -14,12 +14,12 @@ class Authentication(AdCPBaseModel): model_config = ConfigDict( - extra='forbid', + extra="forbid", ) credentials: Annotated[ str, Field( - description='Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.', + description="Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.", min_length=32, ), ] @@ -36,13 +36,13 @@ class Authentication(AdCPBaseModel): class PushNotificationConfig(AdCPBaseModel): authentication: Annotated[ Authentication, - Field(description='Authentication configuration for webhook delivery (A2A-compatible)'), + Field(description="Authentication configuration for webhook delivery (A2A-compatible)"), ] token: Annotated[ str | None, Field( - description='Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.', + description="Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.", min_length=16, ), ] = None - url: Annotated[AnyUrl, Field(description='Webhook endpoint URL for task status notifications')] + url: Annotated[AnyUrl, Field(description="Webhook endpoint URL for task status notifications")] diff --git a/src/adcp/types/generated_poc/core/reporting_capabilities.py b/src/adcp/types/generated_poc/core/reporting_capabilities.py index 651b6514..3fae8dd7 100644 --- a/src/adcp/types/generated_poc/core/reporting_capabilities.py +++ b/src/adcp/types/generated_poc/core/reporting_capabilities.py @@ -14,38 +14,38 @@ class ReportingCapabilities(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) available_metrics: Annotated[ list[available_metric.AvailableMetric], Field( - description='Metrics available in reporting. Impressions and spend are always implicitly included.', + description="Metrics available in reporting. Impressions and spend are always implicitly included.", examples=[ - ['impressions', 'spend', 'clicks', 'video_completions'], - ['impressions', 'spend', 'conversions'], + ["impressions", "spend", "clicks", "video_completions"], + ["impressions", "spend", "conversions"], ], ), ] available_reporting_frequencies: Annotated[ list[reporting_frequency.ReportingFrequency], - Field(description='Supported reporting frequency options', min_length=1), + Field(description="Supported reporting frequency options", min_length=1), ] expected_delay_minutes: Annotated[ int, Field( - description='Expected delay in minutes before reporting data becomes available (e.g., 240 for 4-hour delay)', + description="Expected delay in minutes before reporting data becomes available (e.g., 240 for 4-hour delay)", examples=[240, 300, 1440], ge=0, ), ] supports_webhooks: Annotated[ bool, - Field(description='Whether this product supports webhook-based reporting notifications'), + Field(description="Whether this product supports webhook-based reporting notifications"), ] timezone: Annotated[ str, Field( description="Timezone for reporting periods. Use 'UTC' or IANA timezone (e.g., 'America/New_York'). Critical for daily/monthly frequency alignment.", - examples=['UTC', 'America/New_York', 'Europe/London', 'America/Los_Angeles'], + examples=["UTC", "America/New_York", "Europe/London", "America/Los_Angeles"], ), ] diff --git a/src/adcp/types/generated_poc/core/response.py b/src/adcp/types/generated_poc/core/response.py index 343adf1e..a6bbb32a 100644 --- a/src/adcp/types/generated_poc/core/response.py +++ b/src/adcp/types/generated_poc/core/response.py @@ -12,13 +12,13 @@ class ProtocolResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - context_id: Annotated[str | None, Field(description='Session continuity identifier')] = None + context_id: Annotated[str | None, Field(description="Session continuity identifier")] = None data: Annotated[ Any | None, Field( - description='AdCP task-specific response data (see individual task response schemas)' + description="AdCP task-specific response data (see individual task response schemas)" ), ] = None - message: Annotated[str, Field(description='Human-readable summary')] + message: Annotated[str, Field(description="Human-readable summary")] diff --git a/src/adcp/types/generated_poc/core/signal_filters.py b/src/adcp/types/generated_poc/core/signal_filters.py index 142b2864..c16ffcf1 100644 --- a/src/adcp/types/generated_poc/core/signal_filters.py +++ b/src/adcp/types/generated_poc/core/signal_filters.py @@ -14,16 +14,16 @@ class SignalFilters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) catalog_types: Annotated[ list[signal_catalog_type.SignalCatalogType] | None, - Field(description='Filter by catalog type'), + Field(description="Filter by catalog type"), ] = None data_providers: Annotated[ - list[str] | None, Field(description='Filter by specific data providers') + list[str] | None, Field(description="Filter by specific data providers") ] = None - max_cpm: Annotated[float | None, Field(description='Maximum CPM price filter', ge=0.0)] = None + max_cpm: Annotated[float | None, Field(description="Maximum CPM price filter", ge=0.0)] = None min_coverage_percentage: Annotated[ - float | None, Field(description='Minimum coverage requirement', ge=0.0, le=100.0) + float | None, Field(description="Minimum coverage requirement", ge=0.0, le=100.0) ] = None diff --git a/src/adcp/types/generated_poc/core/start_timing.py b/src/adcp/types/generated_poc/core/start_timing.py index 1b9689a7..eb43ec94 100644 --- a/src/adcp/types/generated_poc/core/start_timing.py +++ b/src/adcp/types/generated_poc/core/start_timing.py @@ -1,18 +1,18 @@ # generated by datamodel-codegen: # filename: core/start_timing.json -# timestamp: 2025-12-11T15:09:37+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations -from typing import Annotated +from typing import Annotated, Literal from pydantic import AwareDatetime, Field, RootModel -class StartTiming(RootModel[str | AwareDatetime]): +class StartTiming(RootModel[Literal["asap"] | AwareDatetime]): root: Annotated[ - str | AwareDatetime, + Literal["asap"] | AwareDatetime, Field( - description="Campaign start timing: 'asap' or ISO 8601 date-time", title='Start Timing' + description="Campaign start timing: 'asap' or ISO 8601 date-time", title="Start Timing" ), ] diff --git a/src/adcp/types/generated_poc/core/sub_asset.py b/src/adcp/types/generated_poc/core/sub_asset.py index 469f176c..b7c5cab5 100644 --- a/src/adcp/types/generated_poc/core/sub_asset.py +++ b/src/adcp/types/generated_poc/core/sub_asset.py @@ -12,45 +12,45 @@ class SubAsset1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_id: Annotated[ - str, Field(description='Unique identifier for the asset within the creative') + str, Field(description="Unique identifier for the asset within the creative") ] asset_kind: Annotated[ - Literal['media'], - Field(description='Discriminator indicating this is a media asset with content_uri'), + Literal["media"], + Field(description="Discriminator indicating this is a media asset with content_uri"), ] asset_type: Annotated[ str, Field( - description='Type of asset. Common types: thumbnail_image, product_image, featured_image, logo' + description="Type of asset. Common types: thumbnail_image, product_image, featured_image, logo" ), ] - content_uri: Annotated[AnyUrl, Field(description='URL for media assets (images, videos, etc.)')] + content_uri: Annotated[AnyUrl, Field(description="URL for media assets (images, videos, etc.)")] class SubAsset2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_id: Annotated[ - str, Field(description='Unique identifier for the asset within the creative') + str, Field(description="Unique identifier for the asset within the creative") ] asset_kind: Annotated[ - Literal['text'], - Field(description='Discriminator indicating this is a text asset with content'), + Literal["text"], + Field(description="Discriminator indicating this is a text asset with content"), ] asset_type: Annotated[ str, Field( - description='Type of asset. Common types: headline, body_text, cta_text, price_text, sponsor_name, author_name, click_url' + description="Type of asset. Common types: headline, body_text, cta_text, price_text, sponsor_name, author_name, click_url" ), ] content: Annotated[ str | list[str], Field( - description='Text content for text-based assets like headlines, body text, CTA text, etc.' + description="Text content for text-based assets like headlines, body text, CTA text, etc." ), ] @@ -59,7 +59,7 @@ class SubAsset(RootModel[SubAsset1 | SubAsset2]): root: Annotated[ SubAsset1 | SubAsset2, Field( - description='Sub-asset for multi-asset creative formats, including carousel images and native ad template variables', - title='Sub-Asset', + description="Sub-asset for multi-asset creative formats, including carousel images and native ad template variables", + title="Sub-Asset", ), ] diff --git a/src/adcp/types/generated_poc/core/targeting.py b/src/adcp/types/generated_poc/core/targeting.py index a382182a..d9623c42 100644 --- a/src/adcp/types/generated_poc/core/targeting.py +++ b/src/adcp/types/generated_poc/core/targeting.py @@ -13,41 +13,41 @@ class GeoCountryAnyOfItem(RootModel[str]): - root: Annotated[str, Field(pattern='^[A-Z]{2}$')] + root: Annotated[str, Field(pattern="^[A-Z]{2}$")] class TargetingOverlay(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) axe_exclude_segment: Annotated[ - str | None, Field(description='AXE segment ID to exclude from targeting') + str | None, Field(description="AXE segment ID to exclude from targeting") ] = None axe_include_segment: Annotated[ - str | None, Field(description='AXE segment ID to include for targeting') + str | None, Field(description="AXE segment ID to include for targeting") ] = None frequency_cap: frequency_cap_1.FrequencyCap | None = None geo_country_any_of: Annotated[ list[GeoCountryAnyOfItem] | None, Field( - description='Restrict delivery to specific countries (ISO codes). Use for regulatory compliance or RCT testing.' + description="Restrict delivery to specific countries (ISO codes). Use for regulatory compliance or RCT testing." ), ] = None geo_metro_any_of: Annotated[ list[str] | None, Field( - description='Restrict delivery to specific metro areas (DMA codes). Use for regulatory compliance or RCT testing.' + description="Restrict delivery to specific metro areas (DMA codes). Use for regulatory compliance or RCT testing." ), ] = None geo_postal_code_any_of: Annotated[ list[str] | None, Field( - description='Restrict delivery to specific postal/ZIP codes. Use for regulatory compliance or RCT testing.' + description="Restrict delivery to specific postal/ZIP codes. Use for regulatory compliance or RCT testing." ), ] = None geo_region_any_of: Annotated[ list[str] | None, Field( - description='Restrict delivery to specific regions/states. Use for regulatory compliance or RCT testing.' + description="Restrict delivery to specific regions/states. Use for regulatory compliance or RCT testing." ), ] = None diff --git a/src/adcp/types/generated_poc/creative/list_creative_formats_request.py b/src/adcp/types/generated_poc/creative/list_creative_formats_request.py index 2e9a6214..2f99abc3 100644 --- a/src/adcp/types/generated_poc/creative/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/creative/list_creative_formats_request.py @@ -16,25 +16,25 @@ class AssetType(Enum): - image = 'image' - video = 'video' - audio = 'audio' - text = 'text' - html = 'html' - javascript = 'javascript' - url = 'url' + image = "image" + video = "video" + audio = "audio" + text = "text" + html = "html" + javascript = "javascript" + url = "url" class Type(Enum): - audio = 'audio' - video = 'video' - display = 'display' - dooh = 'dooh' + audio = "audio" + video = "video" + display = "display" + dooh = "dooh" class ListCreativeFormatsRequestCreativeAgent(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_types: Annotated[ list[AssetType] | None, @@ -45,44 +45,44 @@ class ListCreativeFormatsRequestCreativeAgent(AdCPBaseModel): context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None format_ids: Annotated[ - list[format_id.FormatId] | None, Field(description='Return only these specific format IDs') + list[format_id.FormatId] | None, Field(description="Return only these specific format IDs") ] = None is_responsive: Annotated[ bool | None, Field( - description='Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions.' + description="Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions." ), ] = None max_height: Annotated[ int | None, Field( - description='Maximum height in pixels (inclusive). Returns formats with height <= this value. Omit for responsive/fluid formats.' + description="Maximum height in pixels (inclusive). Returns formats with height <= this value. Omit for responsive/fluid formats." ), ] = None max_width: Annotated[ int | None, Field( - description='Maximum width in pixels (inclusive). Returns formats with width <= this value. Omit for responsive/fluid formats.' + description="Maximum width in pixels (inclusive). Returns formats with width <= this value. Omit for responsive/fluid formats." ), ] = None min_height: Annotated[ int | None, Field( - description='Minimum height in pixels (inclusive). Returns formats with height >= this value.' + description="Minimum height in pixels (inclusive). Returns formats with height >= this value." ), ] = None min_width: Annotated[ int | None, Field( - description='Minimum width in pixels (inclusive). Returns formats with width >= this value.' + description="Minimum width in pixels (inclusive). Returns formats with width >= this value." ), ] = None name_search: Annotated[ - str | None, Field(description='Search for formats by name (case-insensitive partial match)') + str | None, Field(description="Search for formats by name (case-insensitive partial match)") ] = None type: Annotated[ Type | None, Field( - description='Filter by format type (technical categories with distinct requirements)' + description="Filter by format type (technical categories with distinct requirements)" ), ] = None diff --git a/src/adcp/types/generated_poc/creative/list_creative_formats_response.py b/src/adcp/types/generated_poc/creative/list_creative_formats_response.py index 5e85ce21..ddb7b6d5 100644 --- a/src/adcp/types/generated_poc/creative/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/creative/list_creative_formats_response.py @@ -18,7 +18,7 @@ class CreativeAgent(AdCPBaseModel): agent_name: Annotated[ - str | None, Field(description='Human-readable name for the creative agent') + str | None, Field(description="Human-readable name for the creative agent") ] = None agent_url: Annotated[ AnyUrl, @@ -28,23 +28,23 @@ class CreativeAgent(AdCPBaseModel): ] capabilities: Annotated[ list[creative_agent_capability.CreativeAgentCapability] | None, - Field(description='Capabilities this creative agent provides'), + Field(description="Capabilities this creative agent provides"), ] = None class ListCreativeFormatsResponseCreativeAgent(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creative_agents: Annotated[ list[CreativeAgent] | None, Field( - description='Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats.' + description="Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats." ), ] = None errors: Annotated[ - list[error.Error] | None, Field(description='Task-specific errors and warnings') + list[error.Error] | None, Field(description="Task-specific errors and warnings") ] = None ext: ext_1.ExtensionObject | None = None formats: Annotated[ diff --git a/src/adcp/types/generated_poc/creative/preview_creative_request.py b/src/adcp/types/generated_poc/creative/preview_creative_request.py index 5b15d6a8..a685d7a7 100644 --- a/src/adcp/types/generated_poc/creative/preview_creative_request.py +++ b/src/adcp/types/generated_poc/creative/preview_creative_request.py @@ -18,7 +18,7 @@ class Input(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context_description: Annotated[ str | None, @@ -42,37 +42,37 @@ class Input(AdCPBaseModel): class Input2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context_description: Annotated[ str | None, - Field(description='Natural language description of the context for AI-generated content'), + Field(description="Natural language description of the context for AI-generated content"), ] = None macros: Annotated[ - dict[str, str] | None, Field(description='Macro values to use for this preview') + dict[str, str] | None, Field(description="Macro values to use for this preview") ] = None - name: Annotated[str, Field(description='Human-readable name for this input set')] + name: Annotated[str, Field(description="Human-readable name for this input set")] class PreviewCreativeRequest1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest, Field( - description='Complete creative manifest with all required assets (including promoted_offerings if required by the format)' + description="Complete creative manifest with all required assets (including promoted_offerings if required by the format)" ), ] ext: ext_1.ExtensionObject | None = None format_id: Annotated[ - format_id_1.FormatId, Field(description='Format identifier for rendering the preview') + format_id_1.FormatId, Field(description="Format identifier for rendering the preview") ] inputs: Annotated[ list[Input] | None, Field( - description='Array of input sets for generating multiple preview variants. Each input set defines macros and context values for one preview rendering. If not provided, creative agent will generate default previews.' + description="Array of input sets for generating multiple preview variants. Each input set defines macros and context values for one preview rendering. If not provided, creative agent will generate default previews." ), ] = None output_format: Annotated[ @@ -82,28 +82,28 @@ class PreviewCreativeRequest1(AdCPBaseModel): ), ] = preview_output_format.PreviewOutputFormat.url request_type: Annotated[ - Literal['single'], - Field(description='Discriminator indicating this is a single preview request'), + Literal["single"], + Field(description="Discriminator indicating this is a single preview request"), ] template_id: Annotated[ - str | None, Field(description='Specific template ID for custom format rendering') + str | None, Field(description="Specific template ID for custom format rendering") ] = None class Request(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) creative_manifest: Annotated[ creative_manifest_1.CreativeManifest, - Field(description='Complete creative manifest with all required assets'), + Field(description="Complete creative manifest with all required assets"), ] format_id: Annotated[ - format_id_1.FormatId, Field(description='Format identifier for rendering the preview') + format_id_1.FormatId, Field(description="Format identifier for rendering the preview") ] inputs: Annotated[ list[Input2] | None, - Field(description='Array of input sets for generating multiple preview variants'), + Field(description="Array of input sets for generating multiple preview variants"), ] = None output_format: Annotated[ preview_output_format.PreviewOutputFormat | None, @@ -112,13 +112,13 @@ class Request(AdCPBaseModel): ), ] = preview_output_format.PreviewOutputFormat.url template_id: Annotated[ - str | None, Field(description='Specific template ID for custom format rendering') + str | None, Field(description="Specific template ID for custom format rendering") ] = None class PreviewCreativeRequest2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None @@ -129,13 +129,13 @@ class PreviewCreativeRequest2(AdCPBaseModel): ), ] = preview_output_format.PreviewOutputFormat.url request_type: Annotated[ - Literal['batch'], - Field(description='Discriminator indicating this is a batch preview request'), + Literal["batch"], + Field(description="Discriminator indicating this is a batch preview request"), ] requests: Annotated[ list[Request], Field( - description='Array of preview requests (1-50 items). Each follows the single request structure.', + description="Array of preview requests (1-50 items). Each follows the single request structure.", max_length=50, min_length=1, ), @@ -146,8 +146,8 @@ class PreviewCreativeRequest(RootModel[PreviewCreativeRequest1 | PreviewCreative root: Annotated[ PreviewCreativeRequest1 | PreviewCreativeRequest2, Field( - discriminator='request_type', - description='Request to generate previews of one or more creative manifests. Accepts either a single creative request or an array of requests for batch processing.', - title='Preview Creative Request', + discriminator="request_type", + description="Request to generate previews of one or more creative manifests. Accepts either a single creative request or an array of requests for batch processing.", + title="Preview Creative Request", ), ] diff --git a/src/adcp/types/generated_poc/creative/preview_creative_response.py b/src/adcp/types/generated_poc/creative/preview_creative_response.py index 8a0282d9..e78e0909 100644 --- a/src/adcp/types/generated_poc/creative/preview_creative_response.py +++ b/src/adcp/types/generated_poc/creative/preview_creative_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: creative/preview_creative_response.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -16,12 +16,12 @@ class Input(AdCPBaseModel): context_description: Annotated[ - str | None, Field(description='Context description applied to this variant') + str | None, Field(description="Context description applied to this variant") ] = None macros: Annotated[ - dict[str, str] | None, Field(description='Macro values applied to this variant') + dict[str, str] | None, Field(description="Macro values applied to this variant") ] = None - name: Annotated[str, Field(description='Human-readable name for this variant')] + name: Annotated[str, Field(description="Human-readable name for this variant")] class Error(AdCPBaseModel): @@ -31,8 +31,8 @@ class Error(AdCPBaseModel): description="Error code (e.g., 'invalid_manifest', 'unsupported_format', 'missing_assets')" ), ] - details: Annotated[dict[str, Any] | None, Field(description='Additional error context')] = None - message: Annotated[str, Field(description='Human-readable error message')] + details: Annotated[dict[str, Any] | None, Field(description="Additional error context")] = None + message: Annotated[str, Field(description="Human-readable error message")] class Input4(AdCPBaseModel): @@ -45,14 +45,14 @@ class Preview(AdCPBaseModel): input: Annotated[ Input, Field( - description='The input parameters that generated this preview variant. Echoes back the request input or shows defaults used.' + description="The input parameters that generated this preview variant. Echoes back the request input or shows defaults used." ), ] - preview_id: Annotated[str, Field(description='Unique identifier for this preview variant')] + preview_id: Annotated[str, Field(description="Unique identifier for this preview variant")] renders: Annotated[ list[preview_render.PreviewRender], Field( - description='Array of rendered pieces for this preview variant. Most formats render as a single piece. Companion ad formats (video + banner), multi-placement formats, and adaptive formats render as multiple pieces.', + description="Array of rendered pieces for this preview variant. Most formats render as a single piece. Companion ad formats (video + banner), multi-placement formats, and adaptive formats render as multiple pieces.", min_length=1, ), ] @@ -60,29 +60,29 @@ class Preview(AdCPBaseModel): class PreviewCreativeResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None expires_at: Annotated[ - AwareDatetime, Field(description='ISO 8601 timestamp when preview links expire') + AwareDatetime, Field(description="ISO 8601 timestamp when preview links expire") ] ext: ext_1.ExtensionObject | None = None interactive_url: Annotated[ AnyUrl | None, Field( - description='Optional URL to an interactive testing page that shows all preview variants with controls to switch between them, modify macro values, and test different scenarios.' + description="Optional URL to an interactive testing page that shows all preview variants with controls to switch between them, modify macro values, and test different scenarios." ), ] = None previews: Annotated[ list[Preview], Field( - description='Array of preview variants. Each preview corresponds to an input set from the request. If no inputs were provided, returns a single default preview.', + description="Array of preview variants. Each preview corresponds to an input set from the request. If no inputs were provided, returns a single default preview.", min_length=1, ), ] response_type: Annotated[ - Literal['single'], - Field(description='Discriminator indicating this is a single preview response'), + Literal["single"], + Field(description="Discriminator indicating this is a single preview response"), ] @@ -97,19 +97,20 @@ class Response(AdCPBaseModel): interactive_url: AnyUrl | None = None previews: Annotated[ list[Preview1], - Field(description='Array of preview variants for this creative', min_length=1), + Field(description="Array of preview variants for this creative", min_length=1), ] class Results(AdCPBaseModel): - error: Annotated[Error | None, Field(description='Error information for failed requests')] = ( + error: Annotated[Error | None, Field(description="Error information for failed requests")] = ( None ) - response: Annotated[Response, Field(description='Preview response for successful requests')] - success: Annotated[Literal[True], Field(description='Whether this preview request succeeded')] + response: Annotated[Response, Field(description="Preview response for successful requests")] + success: Annotated[Literal[True], Field(description="Whether this preview request succeeded")] -Preview2 = Preview1 +class Preview2(Preview1): + pass class Response1(AdCPBaseModel): @@ -117,32 +118,32 @@ class Response1(AdCPBaseModel): interactive_url: AnyUrl | None = None previews: Annotated[ list[Preview2], - Field(description='Array of preview variants for this creative', min_length=1), + Field(description="Array of preview variants for this creative", min_length=1), ] class Results1(AdCPBaseModel): - error: Annotated[Error, Field(description='Error information for failed requests')] + error: Annotated[Error, Field(description="Error information for failed requests")] response: Annotated[ - Response1 | None, Field(description='Preview response for successful requests') + Response1 | None, Field(description="Preview response for successful requests") ] = None - success: Annotated[Literal[False], Field(description='Whether this preview request succeeded')] + success: Annotated[Literal[False], Field(description="Whether this preview request succeeded")] class PreviewCreativeResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None response_type: Annotated[ - Literal['batch'], - Field(description='Discriminator indicating this is a batch preview response'), + Literal["batch"], + Field(description="Discriminator indicating this is a batch preview response"), ] results: Annotated[ list[Results | Results1], Field( - description='Array of preview results corresponding to each request in the same order. results[0] is the result for requests[0], results[1] for requests[1], etc. Order is guaranteed even when some requests fail. Each result contains either a successful preview response or an error.', + description="Array of preview results corresponding to each request in the same order. results[0] is the result for requests[0], results[1] for requests[1], etc. Order is guaranteed even when some requests fail. Each result contains either a successful preview response or an error.", min_length=1, ), ] @@ -152,7 +153,7 @@ class PreviewCreativeResponse(RootModel[PreviewCreativeResponse1 | PreviewCreati root: Annotated[ PreviewCreativeResponse1 | PreviewCreativeResponse2, Field( - description='Response containing preview links for one or more creatives. Format matches the request: single preview response for single requests, batch results for batch requests.', - title='Preview Creative Response', + description="Response containing preview links for one or more creatives. Format matches the request: single preview response for single requests, batch results for batch requests.", + title="Preview Creative Response", ), ] diff --git a/src/adcp/types/generated_poc/creative/preview_render.py b/src/adcp/types/generated_poc/creative/preview_render.py index f5c8ac78..1a19ba57 100644 --- a/src/adcp/types/generated_poc/creative/preview_render.py +++ b/src/adcp/types/generated_poc/creative/preview_render.py @@ -17,7 +17,7 @@ class Dimensions(AdCPBaseModel): class Embedding(AdCPBaseModel): csp_policy: Annotated[ - str | None, Field(description='Content Security Policy requirements for embedding') + str | None, Field(description="Content Security Policy requirements for embedding") ] = None recommended_sandbox: Annotated[ str | None, @@ -26,35 +26,35 @@ class Embedding(AdCPBaseModel): ), ] = None requires_https: Annotated[ - bool | None, Field(description='Whether this output requires HTTPS for secure embedding') + bool | None, Field(description="Whether this output requires HTTPS for secure embedding") ] = None supports_fullscreen: Annotated[ - bool | None, Field(description='Whether this output supports fullscreen mode') + bool | None, Field(description="Whether this output supports fullscreen mode") ] = None class PreviewRender1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) dimensions: Annotated[ - Dimensions | None, Field(description='Dimensions for this rendered piece') + Dimensions | None, Field(description="Dimensions for this rendered piece") ] = None embedding: Annotated[ Embedding | None, - Field(description='Optional security and embedding metadata for safe iframe integration'), + Field(description="Optional security and embedding metadata for safe iframe integration"), ] = None output_format: Annotated[ - Literal['url'], Field(description='Discriminator indicating preview_url is provided') + Literal["url"], Field(description="Discriminator indicating preview_url is provided") ] preview_url: Annotated[ AnyUrl, Field( - description='URL to an HTML page that renders this piece. Can be embedded in an iframe.' + description="URL to an HTML page that renders this piece. Can be embedded in an iframe." ), ] render_id: Annotated[ - str, Field(description='Unique identifier for this rendered piece within the variant') + str, Field(description="Unique identifier for this rendered piece within the variant") ] role: Annotated[ str, @@ -66,25 +66,25 @@ class PreviewRender1(AdCPBaseModel): class PreviewRender2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) dimensions: Annotated[ - Dimensions | None, Field(description='Dimensions for this rendered piece') + Dimensions | None, Field(description="Dimensions for this rendered piece") ] = None embedding: Annotated[ - Embedding | None, Field(description='Optional security and embedding metadata') + Embedding | None, Field(description="Optional security and embedding metadata") ] = None output_format: Annotated[ - Literal['html'], Field(description='Discriminator indicating preview_html is provided') + Literal["html"], Field(description="Discriminator indicating preview_html is provided") ] preview_html: Annotated[ str, Field( - description='Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing.' + description="Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing." ), ] render_id: Annotated[ - str, Field(description='Unique identifier for this rendered piece within the variant') + str, Field(description="Unique identifier for this rendered piece within the variant") ] role: Annotated[ str, @@ -96,35 +96,35 @@ class PreviewRender2(AdCPBaseModel): class PreviewRender3(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) dimensions: Annotated[ - Dimensions | None, Field(description='Dimensions for this rendered piece') + Dimensions | None, Field(description="Dimensions for this rendered piece") ] = None embedding: Annotated[ Embedding | None, - Field(description='Optional security and embedding metadata for safe iframe integration'), + Field(description="Optional security and embedding metadata for safe iframe integration"), ] = None output_format: Annotated[ - Literal['both'], + Literal["both"], Field( - description='Discriminator indicating both preview_url and preview_html are provided' + description="Discriminator indicating both preview_url and preview_html are provided" ), ] preview_html: Annotated[ str, Field( - description='Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing.' + description="Raw HTML for this rendered piece. Can be embedded directly in the page without iframe. Security warning: Only use with trusted creative agents as this bypasses iframe sandboxing." ), ] preview_url: Annotated[ AnyUrl, Field( - description='URL to an HTML page that renders this piece. Can be embedded in an iframe.' + description="URL to an HTML page that renders this piece. Can be embedded in an iframe." ), ] render_id: Annotated[ - str, Field(description='Unique identifier for this rendered piece within the variant') + str, Field(description="Unique identifier for this rendered piece within the variant") ] role: Annotated[ str, @@ -138,7 +138,7 @@ class PreviewRender(RootModel[PreviewRender1 | PreviewRender2 | PreviewRender3]) root: Annotated[ PreviewRender1 | PreviewRender2 | PreviewRender3, Field( - description='A single rendered piece of a creative preview with discriminated output format', - title='Preview Render', + description="A single rendered piece of a creative preview with discriminated output format", + title="Preview Render", ), ] diff --git a/src/adcp/types/generated_poc/enums/adcp_domain.py b/src/adcp/types/generated_poc/enums/adcp_domain.py index fe3db830..e736171a 100644 --- a/src/adcp/types/generated_poc/enums/adcp_domain.py +++ b/src/adcp/types/generated_poc/enums/adcp_domain.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/adcp_domain.json -# timestamp: 2025-11-29T12:00:45+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -8,5 +8,7 @@ class AdcpDomain(Enum): - media_buy = 'media-buy' - signals = 'signals' + media_buy = "media-buy" + signals = "signals" + governance = "governance" + creative = "creative" diff --git a/src/adcp/types/generated_poc/enums/asset_content_type.py b/src/adcp/types/generated_poc/enums/asset_content_type.py index a907d9ff..b1c57669 100644 --- a/src/adcp/types/generated_poc/enums/asset_content_type.py +++ b/src/adcp/types/generated_poc/enums/asset_content_type.py @@ -8,16 +8,16 @@ class AssetContentType(Enum): - image = 'image' - video = 'video' - audio = 'audio' - text = 'text' - markdown = 'markdown' - html = 'html' - css = 'css' - javascript = 'javascript' - vast = 'vast' - daast = 'daast' - promoted_offerings = 'promoted_offerings' - url = 'url' - webhook = 'webhook' + image = "image" + video = "video" + audio = "audio" + text = "text" + markdown = "markdown" + html = "html" + css = "css" + javascript = "javascript" + vast = "vast" + daast = "daast" + promoted_offerings = "promoted_offerings" + url = "url" + webhook = "webhook" diff --git a/src/adcp/types/generated_poc/enums/auth_scheme.py b/src/adcp/types/generated_poc/enums/auth_scheme.py index 0956377a..b4bfac14 100644 --- a/src/adcp/types/generated_poc/enums/auth_scheme.py +++ b/src/adcp/types/generated_poc/enums/auth_scheme.py @@ -8,5 +8,5 @@ class AuthenticationScheme(Enum): - Bearer = 'Bearer' - HMAC_SHA256 = 'HMAC-SHA256' + Bearer = "Bearer" + HMAC_SHA256 = "HMAC-SHA256" diff --git a/src/adcp/types/generated_poc/enums/available_metric.py b/src/adcp/types/generated_poc/enums/available_metric.py index 1461bb4a..36365c5b 100644 --- a/src/adcp/types/generated_poc/enums/available_metric.py +++ b/src/adcp/types/generated_poc/enums/available_metric.py @@ -8,12 +8,12 @@ class AvailableMetric(Enum): - impressions = 'impressions' - spend = 'spend' - clicks = 'clicks' - ctr = 'ctr' - video_completions = 'video_completions' - completion_rate = 'completion_rate' - conversions = 'conversions' - viewability = 'viewability' - engagement_rate = 'engagement_rate' + impressions = "impressions" + spend = "spend" + clicks = "clicks" + ctr = "ctr" + video_completions = "video_completions" + completion_rate = "completion_rate" + conversions = "conversions" + viewability = "viewability" + engagement_rate = "engagement_rate" diff --git a/src/adcp/types/generated_poc/enums/channels.py b/src/adcp/types/generated_poc/enums/channels.py index 0f44d698..82f32a1c 100644 --- a/src/adcp/types/generated_poc/enums/channels.py +++ b/src/adcp/types/generated_poc/enums/channels.py @@ -8,12 +8,12 @@ class AdvertisingChannels(Enum): - display = 'display' - video = 'video' - audio = 'audio' - native = 'native' - dooh = 'dooh' - ctv = 'ctv' - podcast = 'podcast' - retail = 'retail' - social = 'social' + display = "display" + video = "video" + audio = "audio" + native = "native" + dooh = "dooh" + ctv = "ctv" + podcast = "podcast" + retail = "retail" + social = "social" diff --git a/src/adcp/types/generated_poc/enums/co_branding_requirement.py b/src/adcp/types/generated_poc/enums/co_branding_requirement.py index 0dffa627..b959ac6d 100644 --- a/src/adcp/types/generated_poc/enums/co_branding_requirement.py +++ b/src/adcp/types/generated_poc/enums/co_branding_requirement.py @@ -8,6 +8,6 @@ class CoBrandingRequirement(Enum): - required = 'required' - optional = 'optional' - none = 'none' + required = "required" + optional = "optional" + none = "none" diff --git a/src/adcp/types/generated_poc/enums/creative_action.py b/src/adcp/types/generated_poc/enums/creative_action.py index 094099c6..535ba3f4 100644 --- a/src/adcp/types/generated_poc/enums/creative_action.py +++ b/src/adcp/types/generated_poc/enums/creative_action.py @@ -8,8 +8,8 @@ class CreativeAction(Enum): - created = 'created' - updated = 'updated' - unchanged = 'unchanged' - failed = 'failed' - deleted = 'deleted' + created = "created" + updated = "updated" + unchanged = "unchanged" + failed = "failed" + deleted = "deleted" diff --git a/src/adcp/types/generated_poc/enums/creative_agent_capability.py b/src/adcp/types/generated_poc/enums/creative_agent_capability.py index cc3fdbee..444595f1 100644 --- a/src/adcp/types/generated_poc/enums/creative_agent_capability.py +++ b/src/adcp/types/generated_poc/enums/creative_agent_capability.py @@ -8,7 +8,7 @@ class CreativeAgentCapability(Enum): - validation = 'validation' - assembly = 'assembly' - generation = 'generation' - preview = 'preview' + validation = "validation" + assembly = "assembly" + generation = "generation" + preview = "preview" diff --git a/src/adcp/types/generated_poc/enums/creative_sort_field.py b/src/adcp/types/generated_poc/enums/creative_sort_field.py index b192ceba..b42ffb46 100644 --- a/src/adcp/types/generated_poc/enums/creative_sort_field.py +++ b/src/adcp/types/generated_poc/enums/creative_sort_field.py @@ -8,9 +8,9 @@ class CreativeSortField(Enum): - created_date = 'created_date' - updated_date = 'updated_date' - name = 'name' - status = 'status' - assignment_count = 'assignment_count' - performance_score = 'performance_score' + created_date = "created_date" + updated_date = "updated_date" + name = "name" + status = "status" + assignment_count = "assignment_count" + performance_score = "performance_score" diff --git a/src/adcp/types/generated_poc/enums/creative_status.py b/src/adcp/types/generated_poc/enums/creative_status.py index 88a81085..227c0755 100644 --- a/src/adcp/types/generated_poc/enums/creative_status.py +++ b/src/adcp/types/generated_poc/enums/creative_status.py @@ -8,7 +8,7 @@ class CreativeStatus(Enum): - processing = 'processing' - approved = 'approved' - rejected = 'rejected' - pending_review = 'pending_review' + processing = "processing" + approved = "approved" + rejected = "rejected" + pending_review = "pending_review" diff --git a/src/adcp/types/generated_poc/enums/daast_tracking_event.py b/src/adcp/types/generated_poc/enums/daast_tracking_event.py index 6b696890..a9caa261 100644 --- a/src/adcp/types/generated_poc/enums/daast_tracking_event.py +++ b/src/adcp/types/generated_poc/enums/daast_tracking_event.py @@ -8,14 +8,14 @@ class DaastTrackingEvent(Enum): - start = 'start' - firstQuartile = 'firstQuartile' - midpoint = 'midpoint' - thirdQuartile = 'thirdQuartile' - complete = 'complete' - impression = 'impression' - pause = 'pause' - resume = 'resume' - skip = 'skip' - mute = 'mute' - unmute = 'unmute' + start = "start" + firstQuartile = "firstQuartile" + midpoint = "midpoint" + thirdQuartile = "thirdQuartile" + complete = "complete" + impression = "impression" + pause = "pause" + resume = "resume" + skip = "skip" + mute = "mute" + unmute = "unmute" diff --git a/src/adcp/types/generated_poc/enums/daast_version.py b/src/adcp/types/generated_poc/enums/daast_version.py index cfeaa1fd..5f07de29 100644 --- a/src/adcp/types/generated_poc/enums/daast_version.py +++ b/src/adcp/types/generated_poc/enums/daast_version.py @@ -8,5 +8,5 @@ class DaastVersion(Enum): - field_1_0 = '1.0' - field_1_1 = '1.1' + field_1_0 = "1.0" + field_1_1 = "1.1" diff --git a/src/adcp/types/generated_poc/enums/delivery_type.py b/src/adcp/types/generated_poc/enums/delivery_type.py index 5392a459..f2b48f80 100644 --- a/src/adcp/types/generated_poc/enums/delivery_type.py +++ b/src/adcp/types/generated_poc/enums/delivery_type.py @@ -8,5 +8,5 @@ class DeliveryType(Enum): - guaranteed = 'guaranteed' - non_guaranteed = 'non_guaranteed' + guaranteed = "guaranteed" + non_guaranteed = "non_guaranteed" diff --git a/src/adcp/types/generated_poc/enums/dimension_unit.py b/src/adcp/types/generated_poc/enums/dimension_unit.py index 01fc1198..714afd26 100644 --- a/src/adcp/types/generated_poc/enums/dimension_unit.py +++ b/src/adcp/types/generated_poc/enums/dimension_unit.py @@ -8,7 +8,7 @@ class DimensionUnit(Enum): - px = 'px' - dp = 'dp' - inches = 'inches' - cm = 'cm' + px = "px" + dp = "dp" + inches = "inches" + cm = "cm" diff --git a/src/adcp/types/generated_poc/enums/feed_format.py b/src/adcp/types/generated_poc/enums/feed_format.py index 2e7d5185..da7f5e1e 100644 --- a/src/adcp/types/generated_poc/enums/feed_format.py +++ b/src/adcp/types/generated_poc/enums/feed_format.py @@ -8,6 +8,6 @@ class FeedFormat(Enum): - google_merchant_center = 'google_merchant_center' - facebook_catalog = 'facebook_catalog' - custom = 'custom' + google_merchant_center = "google_merchant_center" + facebook_catalog = "facebook_catalog" + custom = "custom" diff --git a/src/adcp/types/generated_poc/enums/feedback_source.py b/src/adcp/types/generated_poc/enums/feedback_source.py index d8b8cca6..6027078a 100644 --- a/src/adcp/types/generated_poc/enums/feedback_source.py +++ b/src/adcp/types/generated_poc/enums/feedback_source.py @@ -8,7 +8,7 @@ class FeedbackSource(Enum): - buyer_attribution = 'buyer_attribution' - third_party_measurement = 'third_party_measurement' - platform_analytics = 'platform_analytics' - verification_partner = 'verification_partner' + buyer_attribution = "buyer_attribution" + third_party_measurement = "third_party_measurement" + platform_analytics = "platform_analytics" + verification_partner = "verification_partner" diff --git a/src/adcp/types/generated_poc/enums/format_category.py b/src/adcp/types/generated_poc/enums/format_category.py index 033370f5..da0d4d9f 100644 --- a/src/adcp/types/generated_poc/enums/format_category.py +++ b/src/adcp/types/generated_poc/enums/format_category.py @@ -8,10 +8,10 @@ class FormatCategory(Enum): - audio = 'audio' - video = 'video' - display = 'display' - native = 'native' - dooh = 'dooh' - rich_media = 'rich_media' - universal = 'universal' + audio = "audio" + video = "video" + display = "display" + native = "native" + dooh = "dooh" + rich_media = "rich_media" + universal = "universal" diff --git a/src/adcp/types/generated_poc/enums/format_id_parameter.py b/src/adcp/types/generated_poc/enums/format_id_parameter.py index f8335af2..dd3f1cdb 100644 --- a/src/adcp/types/generated_poc/enums/format_id_parameter.py +++ b/src/adcp/types/generated_poc/enums/format_id_parameter.py @@ -8,5 +8,5 @@ class FormatIdParameter(Enum): - dimensions = 'dimensions' - duration = 'duration' + dimensions = "dimensions" + duration = "duration" diff --git a/src/adcp/types/generated_poc/enums/frequency_cap_scope.py b/src/adcp/types/generated_poc/enums/frequency_cap_scope.py index b2245042..fe91d391 100644 --- a/src/adcp/types/generated_poc/enums/frequency_cap_scope.py +++ b/src/adcp/types/generated_poc/enums/frequency_cap_scope.py @@ -9,8 +9,8 @@ from pydantic import Field, RootModel -class FrequencyCapScope(RootModel[Literal['package']]): +class FrequencyCapScope(RootModel[Literal["package"]]): root: Annotated[ - Literal['package'], - Field(description='Scope for frequency cap application', title='Frequency Cap Scope'), + Literal["package"], + Field(description="Scope for frequency cap application", title="Frequency Cap Scope"), ] diff --git a/src/adcp/types/generated_poc/enums/history_entry_type.py b/src/adcp/types/generated_poc/enums/history_entry_type.py index 0159b0b3..e628d2d1 100644 --- a/src/adcp/types/generated_poc/enums/history_entry_type.py +++ b/src/adcp/types/generated_poc/enums/history_entry_type.py @@ -8,5 +8,5 @@ class HistoryEntryType(Enum): - request = 'request' - response = 'response' + request = "request" + response = "response" diff --git a/src/adcp/types/generated_poc/enums/http_method.py b/src/adcp/types/generated_poc/enums/http_method.py index 67c7fa6c..165725e4 100644 --- a/src/adcp/types/generated_poc/enums/http_method.py +++ b/src/adcp/types/generated_poc/enums/http_method.py @@ -8,5 +8,5 @@ class HttpMethod(Enum): - GET = 'GET' - POST = 'POST' + GET = "GET" + POST = "POST" diff --git a/src/adcp/types/generated_poc/enums/identifier_types.py b/src/adcp/types/generated_poc/enums/identifier_types.py index 8e4bbae1..8bd44883 100644 --- a/src/adcp/types/generated_poc/enums/identifier_types.py +++ b/src/adcp/types/generated_poc/enums/identifier_types.py @@ -8,22 +8,22 @@ class PropertyIdentifierTypes(Enum): - domain = 'domain' - subdomain = 'subdomain' - network_id = 'network_id' - ios_bundle = 'ios_bundle' - android_package = 'android_package' - apple_app_store_id = 'apple_app_store_id' - google_play_id = 'google_play_id' - roku_store_id = 'roku_store_id' - fire_tv_asin = 'fire_tv_asin' - samsung_app_id = 'samsung_app_id' - apple_tv_bundle = 'apple_tv_bundle' - bundle_id = 'bundle_id' - venue_id = 'venue_id' - screen_id = 'screen_id' - openooh_venue_type = 'openooh_venue_type' - rss_url = 'rss_url' - apple_podcast_id = 'apple_podcast_id' - spotify_show_id = 'spotify_show_id' - podcast_guid = 'podcast_guid' + domain = "domain" + subdomain = "subdomain" + network_id = "network_id" + ios_bundle = "ios_bundle" + android_package = "android_package" + apple_app_store_id = "apple_app_store_id" + google_play_id = "google_play_id" + roku_store_id = "roku_store_id" + fire_tv_asin = "fire_tv_asin" + samsung_app_id = "samsung_app_id" + apple_tv_bundle = "apple_tv_bundle" + bundle_id = "bundle_id" + venue_id = "venue_id" + screen_id = "screen_id" + openooh_venue_type = "openooh_venue_type" + rss_url = "rss_url" + apple_podcast_id = "apple_podcast_id" + spotify_show_id = "spotify_show_id" + podcast_guid = "podcast_guid" diff --git a/src/adcp/types/generated_poc/enums/javascript_module_type.py b/src/adcp/types/generated_poc/enums/javascript_module_type.py index 814cfc96..e03b4b6c 100644 --- a/src/adcp/types/generated_poc/enums/javascript_module_type.py +++ b/src/adcp/types/generated_poc/enums/javascript_module_type.py @@ -8,6 +8,6 @@ class JavascriptModuleType(Enum): - esm = 'esm' - commonjs = 'commonjs' - script = 'script' + esm = "esm" + commonjs = "commonjs" + script = "script" diff --git a/src/adcp/types/generated_poc/enums/landing_page_requirement.py b/src/adcp/types/generated_poc/enums/landing_page_requirement.py index 909fd41d..7751357a 100644 --- a/src/adcp/types/generated_poc/enums/landing_page_requirement.py +++ b/src/adcp/types/generated_poc/enums/landing_page_requirement.py @@ -8,6 +8,6 @@ class LandingPageRequirement(Enum): - any = 'any' - retailer_site_only = 'retailer_site_only' - must_include_retailer = 'must_include_retailer' + any = "any" + retailer_site_only = "retailer_site_only" + must_include_retailer = "must_include_retailer" diff --git a/src/adcp/types/generated_poc/enums/markdown_flavor.py b/src/adcp/types/generated_poc/enums/markdown_flavor.py index de8f6633..84b7ca25 100644 --- a/src/adcp/types/generated_poc/enums/markdown_flavor.py +++ b/src/adcp/types/generated_poc/enums/markdown_flavor.py @@ -8,5 +8,5 @@ class MarkdownFlavor(Enum): - commonmark = 'commonmark' - gfm = 'gfm' + commonmark = "commonmark" + gfm = "gfm" diff --git a/src/adcp/types/generated_poc/enums/media_buy_status.py b/src/adcp/types/generated_poc/enums/media_buy_status.py index e3ba6d88..463ff984 100644 --- a/src/adcp/types/generated_poc/enums/media_buy_status.py +++ b/src/adcp/types/generated_poc/enums/media_buy_status.py @@ -8,7 +8,7 @@ class MediaBuyStatus(Enum): - pending_activation = 'pending_activation' - active = 'active' - paused = 'paused' - completed = 'completed' + pending_activation = "pending_activation" + active = "active" + paused = "paused" + completed = "completed" diff --git a/src/adcp/types/generated_poc/enums/metric_type.py b/src/adcp/types/generated_poc/enums/metric_type.py index 4b684e9e..053b9616 100644 --- a/src/adcp/types/generated_poc/enums/metric_type.py +++ b/src/adcp/types/generated_poc/enums/metric_type.py @@ -8,11 +8,11 @@ class MetricType(Enum): - overall_performance = 'overall_performance' - conversion_rate = 'conversion_rate' - brand_lift = 'brand_lift' - click_through_rate = 'click_through_rate' - completion_rate = 'completion_rate' - viewability = 'viewability' - brand_safety = 'brand_safety' - cost_efficiency = 'cost_efficiency' + overall_performance = "overall_performance" + conversion_rate = "conversion_rate" + brand_lift = "brand_lift" + click_through_rate = "click_through_rate" + completion_rate = "completion_rate" + viewability = "viewability" + brand_safety = "brand_safety" + cost_efficiency = "cost_efficiency" diff --git a/src/adcp/types/generated_poc/enums/notification_type.py b/src/adcp/types/generated_poc/enums/notification_type.py index 0edda630..5c3fd9de 100644 --- a/src/adcp/types/generated_poc/enums/notification_type.py +++ b/src/adcp/types/generated_poc/enums/notification_type.py @@ -8,7 +8,7 @@ class NotificationType(Enum): - scheduled = 'scheduled' - final = 'final' - delayed = 'delayed' - adjusted = 'adjusted' + scheduled = "scheduled" + final = "final" + delayed = "delayed" + adjusted = "adjusted" diff --git a/src/adcp/types/generated_poc/enums/pacing.py b/src/adcp/types/generated_poc/enums/pacing.py index 550373bb..768f39fd 100644 --- a/src/adcp/types/generated_poc/enums/pacing.py +++ b/src/adcp/types/generated_poc/enums/pacing.py @@ -8,6 +8,6 @@ class Pacing(Enum): - even = 'even' - asap = 'asap' - front_loaded = 'front_loaded' + even = "even" + asap = "asap" + front_loaded = "front_loaded" diff --git a/src/adcp/types/generated_poc/enums/preview_output_format.py b/src/adcp/types/generated_poc/enums/preview_output_format.py index 004d8405..48f96c1c 100644 --- a/src/adcp/types/generated_poc/enums/preview_output_format.py +++ b/src/adcp/types/generated_poc/enums/preview_output_format.py @@ -8,5 +8,5 @@ class PreviewOutputFormat(Enum): - url = 'url' - html = 'html' + url = "url" + html = "html" diff --git a/src/adcp/types/generated_poc/enums/pricing_model.py b/src/adcp/types/generated_poc/enums/pricing_model.py index 3478ea6d..2a166afb 100644 --- a/src/adcp/types/generated_poc/enums/pricing_model.py +++ b/src/adcp/types/generated_poc/enums/pricing_model.py @@ -8,10 +8,10 @@ class PricingModel(Enum): - cpm = 'cpm' - vcpm = 'vcpm' - cpc = 'cpc' - cpcv = 'cpcv' - cpv = 'cpv' - cpp = 'cpp' - flat_rate = 'flat_rate' + cpm = "cpm" + vcpm = "vcpm" + cpc = "cpc" + cpcv = "cpcv" + cpv = "cpv" + cpp = "cpp" + flat_rate = "flat_rate" diff --git a/src/adcp/types/generated_poc/enums/property_type.py b/src/adcp/types/generated_poc/enums/property_type.py index 1f0d499a..f37d10d8 100644 --- a/src/adcp/types/generated_poc/enums/property_type.py +++ b/src/adcp/types/generated_poc/enums/property_type.py @@ -8,10 +8,10 @@ class PropertyType(Enum): - website = 'website' - mobile_app = 'mobile_app' - ctv_app = 'ctv_app' - dooh = 'dooh' - podcast = 'podcast' - radio = 'radio' - streaming_audio = 'streaming_audio' + website = "website" + mobile_app = "mobile_app" + ctv_app = "ctv_app" + dooh = "dooh" + podcast = "podcast" + radio = "radio" + streaming_audio = "streaming_audio" diff --git a/src/adcp/types/generated_poc/enums/publisher_identifier_types.py b/src/adcp/types/generated_poc/enums/publisher_identifier_types.py index 438bf2eb..20278e5f 100644 --- a/src/adcp/types/generated_poc/enums/publisher_identifier_types.py +++ b/src/adcp/types/generated_poc/enums/publisher_identifier_types.py @@ -8,8 +8,8 @@ class PublisherIdentifierTypes(Enum): - tag_id = 'tag_id' - duns = 'duns' - lei = 'lei' - seller_id = 'seller_id' - gln = 'gln' + tag_id = "tag_id" + duns = "duns" + lei = "lei" + seller_id = "seller_id" + gln = "gln" diff --git a/src/adcp/types/generated_poc/enums/reporting_frequency.py b/src/adcp/types/generated_poc/enums/reporting_frequency.py index e4379eb3..8d57c071 100644 --- a/src/adcp/types/generated_poc/enums/reporting_frequency.py +++ b/src/adcp/types/generated_poc/enums/reporting_frequency.py @@ -8,6 +8,6 @@ class ReportingFrequency(Enum): - hourly = 'hourly' - daily = 'daily' - monthly = 'monthly' + hourly = "hourly" + daily = "daily" + monthly = "monthly" diff --git a/src/adcp/types/generated_poc/enums/signal_catalog_type.py b/src/adcp/types/generated_poc/enums/signal_catalog_type.py index c0963211..9664c4d3 100644 --- a/src/adcp/types/generated_poc/enums/signal_catalog_type.py +++ b/src/adcp/types/generated_poc/enums/signal_catalog_type.py @@ -8,6 +8,6 @@ class SignalCatalogType(Enum): - marketplace = 'marketplace' - custom = 'custom' - owned = 'owned' + marketplace = "marketplace" + custom = "custom" + owned = "owned" diff --git a/src/adcp/types/generated_poc/enums/sort_direction.py b/src/adcp/types/generated_poc/enums/sort_direction.py index 68621fe3..739a21b6 100644 --- a/src/adcp/types/generated_poc/enums/sort_direction.py +++ b/src/adcp/types/generated_poc/enums/sort_direction.py @@ -8,5 +8,5 @@ class SortDirection(Enum): - asc = 'asc' - desc = 'desc' + asc = "asc" + desc = "desc" diff --git a/src/adcp/types/generated_poc/enums/standard_format_ids.py b/src/adcp/types/generated_poc/enums/standard_format_ids.py index 5e26e6ad..96b4bc8c 100644 --- a/src/adcp/types/generated_poc/enums/standard_format_ids.py +++ b/src/adcp/types/generated_poc/enums/standard_format_ids.py @@ -8,38 +8,38 @@ class StandardFormatIds(Enum): - display_300x250 = 'display_300x250' - display_728x90 = 'display_728x90' - display_320x50 = 'display_320x50' - display_160x600 = 'display_160x600' - display_970x250 = 'display_970x250' - display_336x280 = 'display_336x280' - display_expandable_300x250 = 'display_expandable_300x250' - display_expandable_728x90 = 'display_expandable_728x90' - display_interstitial_320x480 = 'display_interstitial_320x480' - display_interstitial_desktop = 'display_interstitial_desktop' - display_dynamic_300x250 = 'display_dynamic_300x250' - display_responsive = 'display_responsive' - native_in_feed = 'native_in_feed' - native_content_recommendation = 'native_content_recommendation' - native_product = 'native_product' - video_skippable_15s = 'video_skippable_15s' - video_skippable_30s = 'video_skippable_30s' - video_non_skippable_15s = 'video_non_skippable_15s' - video_non_skippable_30s = 'video_non_skippable_30s' - video_outstream_autoplay = 'video_outstream_autoplay' - video_vertical_story = 'video_vertical_story' - video_rewarded_30s = 'video_rewarded_30s' - video_pause_ad = 'video_pause_ad' - video_ctv_non_skippable_30s = 'video_ctv_non_skippable_30s' - audio_standard_15s = 'audio_standard_15s' - audio_standard_30s = 'audio_standard_30s' - audio_podcast_host_read = 'audio_podcast_host_read' - audio_programmatic = 'audio_programmatic' - universal_carousel = 'universal_carousel' - universal_canvas = 'universal_canvas' - universal_takeover = 'universal_takeover' - universal_gallery = 'universal_gallery' - universal_reveal = 'universal_reveal' - dooh_landscape_static = 'dooh_landscape_static' - dooh_portrait_video = 'dooh_portrait_video' + display_300x250 = "display_300x250" + display_728x90 = "display_728x90" + display_320x50 = "display_320x50" + display_160x600 = "display_160x600" + display_970x250 = "display_970x250" + display_336x280 = "display_336x280" + display_expandable_300x250 = "display_expandable_300x250" + display_expandable_728x90 = "display_expandable_728x90" + display_interstitial_320x480 = "display_interstitial_320x480" + display_interstitial_desktop = "display_interstitial_desktop" + display_dynamic_300x250 = "display_dynamic_300x250" + display_responsive = "display_responsive" + native_in_feed = "native_in_feed" + native_content_recommendation = "native_content_recommendation" + native_product = "native_product" + video_skippable_15s = "video_skippable_15s" + video_skippable_30s = "video_skippable_30s" + video_non_skippable_15s = "video_non_skippable_15s" + video_non_skippable_30s = "video_non_skippable_30s" + video_outstream_autoplay = "video_outstream_autoplay" + video_vertical_story = "video_vertical_story" + video_rewarded_30s = "video_rewarded_30s" + video_pause_ad = "video_pause_ad" + video_ctv_non_skippable_30s = "video_ctv_non_skippable_30s" + audio_standard_15s = "audio_standard_15s" + audio_standard_30s = "audio_standard_30s" + audio_podcast_host_read = "audio_podcast_host_read" + audio_programmatic = "audio_programmatic" + universal_carousel = "universal_carousel" + universal_canvas = "universal_canvas" + universal_takeover = "universal_takeover" + universal_gallery = "universal_gallery" + universal_reveal = "universal_reveal" + dooh_landscape_static = "dooh_landscape_static" + dooh_portrait_video = "dooh_portrait_video" diff --git a/src/adcp/types/generated_poc/enums/task_status.py b/src/adcp/types/generated_poc/enums/task_status.py index 6d70d281..24ef178d 100644 --- a/src/adcp/types/generated_poc/enums/task_status.py +++ b/src/adcp/types/generated_poc/enums/task_status.py @@ -8,12 +8,12 @@ class TaskStatus(Enum): - submitted = 'submitted' - working = 'working' - input_required = 'input-required' - completed = 'completed' - canceled = 'canceled' - failed = 'failed' - rejected = 'rejected' - auth_required = 'auth-required' - unknown = 'unknown' + submitted = "submitted" + working = "working" + input_required = "input-required" + completed = "completed" + canceled = "canceled" + failed = "failed" + rejected = "rejected" + auth_required = "auth-required" + unknown = "unknown" diff --git a/src/adcp/types/generated_poc/enums/task_type.py b/src/adcp/types/generated_poc/enums/task_type.py index bd5a3e86..ccaa586c 100644 --- a/src/adcp/types/generated_poc/enums/task_type.py +++ b/src/adcp/types/generated_poc/enums/task_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: enums/task_type.json -# timestamp: 2025-11-29T12:00:45+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -8,8 +8,14 @@ class TaskType(Enum): - create_media_buy = 'create_media_buy' - update_media_buy = 'update_media_buy' - sync_creatives = 'sync_creatives' - activate_signal = 'activate_signal' - get_signals = 'get_signals' + create_media_buy = "create_media_buy" + update_media_buy = "update_media_buy" + sync_creatives = "sync_creatives" + activate_signal = "activate_signal" + get_signals = "get_signals" + list_property_features = "list_property_features" + create_property_list = "create_property_list" + update_property_list = "update_property_list" + get_property_list = "get_property_list" + list_property_lists = "list_property_lists" + delete_property_list = "delete_property_list" diff --git a/src/adcp/types/generated_poc/enums/update_frequency.py b/src/adcp/types/generated_poc/enums/update_frequency.py index 5e850d5f..bb34789c 100644 --- a/src/adcp/types/generated_poc/enums/update_frequency.py +++ b/src/adcp/types/generated_poc/enums/update_frequency.py @@ -8,7 +8,7 @@ class UpdateFrequency(Enum): - realtime = 'realtime' - hourly = 'hourly' - daily = 'daily' - weekly = 'weekly' + realtime = "realtime" + hourly = "hourly" + daily = "daily" + weekly = "weekly" diff --git a/src/adcp/types/generated_poc/enums/url_asset_type.py b/src/adcp/types/generated_poc/enums/url_asset_type.py index 90624e2a..6f71b06d 100644 --- a/src/adcp/types/generated_poc/enums/url_asset_type.py +++ b/src/adcp/types/generated_poc/enums/url_asset_type.py @@ -8,6 +8,6 @@ class UrlAssetType(Enum): - clickthrough = 'clickthrough' - tracker_pixel = 'tracker_pixel' - tracker_script = 'tracker_script' + clickthrough = "clickthrough" + tracker_pixel = "tracker_pixel" + tracker_script = "tracker_script" diff --git a/src/adcp/types/generated_poc/enums/validation_mode.py b/src/adcp/types/generated_poc/enums/validation_mode.py index fc606c98..f2f5acae 100644 --- a/src/adcp/types/generated_poc/enums/validation_mode.py +++ b/src/adcp/types/generated_poc/enums/validation_mode.py @@ -8,5 +8,5 @@ class ValidationMode(Enum): - strict = 'strict' - lenient = 'lenient' + strict = "strict" + lenient = "lenient" diff --git a/src/adcp/types/generated_poc/enums/vast_tracking_event.py b/src/adcp/types/generated_poc/enums/vast_tracking_event.py index e1fd96c2..9ac14497 100644 --- a/src/adcp/types/generated_poc/enums/vast_tracking_event.py +++ b/src/adcp/types/generated_poc/enums/vast_tracking_event.py @@ -8,19 +8,19 @@ class VastTrackingEvent(Enum): - start = 'start' - firstQuartile = 'firstQuartile' - midpoint = 'midpoint' - thirdQuartile = 'thirdQuartile' - complete = 'complete' - impression = 'impression' - click = 'click' - pause = 'pause' - resume = 'resume' - skip = 'skip' - mute = 'mute' - unmute = 'unmute' - fullscreen = 'fullscreen' - exitFullscreen = 'exitFullscreen' - playerExpand = 'playerExpand' - playerCollapse = 'playerCollapse' + start = "start" + firstQuartile = "firstQuartile" + midpoint = "midpoint" + thirdQuartile = "thirdQuartile" + complete = "complete" + impression = "impression" + click = "click" + pause = "pause" + resume = "resume" + skip = "skip" + mute = "mute" + unmute = "unmute" + fullscreen = "fullscreen" + exitFullscreen = "exitFullscreen" + playerExpand = "playerExpand" + playerCollapse = "playerCollapse" diff --git a/src/adcp/types/generated_poc/enums/vast_version.py b/src/adcp/types/generated_poc/enums/vast_version.py index 0838a021..e88efe70 100644 --- a/src/adcp/types/generated_poc/enums/vast_version.py +++ b/src/adcp/types/generated_poc/enums/vast_version.py @@ -8,8 +8,8 @@ class VastVersion(Enum): - field_2_0 = '2.0' - field_3_0 = '3.0' - field_4_0 = '4.0' - field_4_1 = '4.1' - field_4_2 = '4.2' + field_2_0 = "2.0" + field_3_0 = "3.0" + field_4_0 = "4.0" + field_4_1 = "4.1" + field_4_2 = "4.2" diff --git a/src/adcp/types/generated_poc/enums/webhook_response_type.py b/src/adcp/types/generated_poc/enums/webhook_response_type.py index be7a006a..47d9e44c 100644 --- a/src/adcp/types/generated_poc/enums/webhook_response_type.py +++ b/src/adcp/types/generated_poc/enums/webhook_response_type.py @@ -8,7 +8,7 @@ class WebhookResponseType(Enum): - html = 'html' - json = 'json' - xml = 'xml' - javascript = 'javascript' + html = "html" + json = "json" + xml = "xml" + javascript = "javascript" diff --git a/src/adcp/types/generated_poc/enums/webhook_security_method.py b/src/adcp/types/generated_poc/enums/webhook_security_method.py index f51487c4..1b13676a 100644 --- a/src/adcp/types/generated_poc/enums/webhook_security_method.py +++ b/src/adcp/types/generated_poc/enums/webhook_security_method.py @@ -8,6 +8,6 @@ class WebhookSecurityMethod(Enum): - hmac_sha256 = 'hmac_sha256' - api_key = 'api_key' - none = 'none' + hmac_sha256 = "hmac_sha256" + api_key = "api_key" + none = "none" diff --git a/src/adcp/types/generated_poc/extensions/__init__.py b/src/adcp/types/generated_poc/extensions/__init__.py new file mode 100644 index 00000000..5334de51 --- /dev/null +++ b/src/adcp/types/generated_poc/extensions/__init__.py @@ -0,0 +1,3 @@ +# generated by datamodel-codegen: +# filename: .schema_temp +# timestamp: 2026-01-14T17:08:13+00:00 diff --git a/src/adcp/types/generated_poc/extensions/extension_meta.py b/src/adcp/types/generated_poc/extensions/extension_meta.py new file mode 100644 index 00000000..7015338b --- /dev/null +++ b/src/adcp/types/generated_poc/extensions/extension_meta.py @@ -0,0 +1,50 @@ +# generated by datamodel-codegen: +# filename: extensions/extension_meta.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated, Any, Literal + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, Field + + +class AdcpExtensionFileSchema(AdCPBaseModel): + field_schema: Annotated[ + Literal["http://json-schema.org/draft-07/schema#"], Field(alias="$schema") + ] + additionalProperties: Annotated[ + Any | None, + Field(description="Whether additional properties are allowed in the extension data"), + ] = None + description: Annotated[str, Field(description="Description of what this extension provides")] + docs_url: Annotated[ + AnyUrl | None, Field(description="URL to documentation for implementors of this extension") + ] = None + properties: Annotated[ + dict[str, Any], + Field(description="Schema properties defining the structure of ext.{namespace} data"), + ] + required: Annotated[ + list[str] | None, Field(description="Required properties within the extension data") + ] = None + title: Annotated[str, Field(description="Human-readable title for the extension")] + type: Annotated[ + Literal["object"], + Field(description="Extensions must be objects (data within ext.{namespace})"), + ] + valid_from: Annotated[ + str, + Field( + description="Minimum AdCP version this extension is compatible with (e.g., '2.5'). Extension will be included in all versioned schema builds >= this version.", + pattern="^\\d+\\.\\d+$", + ), + ] + valid_until: Annotated[ + str | None, + Field( + description="Last AdCP version this extension is compatible with (e.g., '3.0'). Omit if extension is still valid for current and future versions.", + pattern="^\\d+\\.\\d+$", + ), + ] = None diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_request.py b/src/adcp/types/generated_poc/media_buy/build_creative_request.py index 1b88ee97..1d9d2b9d 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_request.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_request.py @@ -17,25 +17,25 @@ class BuildCreativeRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest | None, Field( - description='Creative manifest to transform or generate from. For pure generation, this should include the target format_id and any required input assets (e.g., promoted_offerings for generative formats). For transformation (e.g., resizing, reformatting), this is the complete creative to adapt.' + description="Creative manifest to transform or generate from. For pure generation, this should include the target format_id and any required input assets (e.g., promoted_offerings for generative formats). For transformation (e.g., resizing, reformatting), this is the complete creative to adapt." ), ] = None ext: ext_1.ExtensionObject | None = None message: Annotated[ str | None, Field( - description='Natural language instructions for the transformation or generation. For pure generation, this is the creative brief. For transformation, this provides guidance on how to adapt the creative.' + description="Natural language instructions for the transformation or generation. For pure generation, this is the creative brief. For transformation, this provides guidance on how to adapt the creative." ), ] = None target_format_id: Annotated[ format_id.FormatId, Field( - description='Format ID to generate. The format definition specifies required input assets and output structure.' + description="Format ID to generate. The format definition specifies required input assets and output structure." ), ] diff --git a/src/adcp/types/generated_poc/media_buy/build_creative_response.py b/src/adcp/types/generated_poc/media_buy/build_creative_response.py index cb89baea..034c573a 100644 --- a/src/adcp/types/generated_poc/media_buy/build_creative_response.py +++ b/src/adcp/types/generated_poc/media_buy/build_creative_response.py @@ -17,13 +17,13 @@ class BuildCreativeResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], Field( - description='Array of errors explaining why creative generation failed', min_length=1 + description="Array of errors explaining why creative generation failed", min_length=1 ), ] ext: ext_1.ExtensionObject | None = None @@ -31,12 +31,12 @@ class BuildCreativeResponse2(AdCPBaseModel): class BuildCreativeResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creative_manifest: Annotated[ creative_manifest_1.CreativeManifest, - Field(description='The generated or transformed creative manifest'), + Field(description="The generated or transformed creative manifest"), ] ext: ext_1.ExtensionObject | None = None @@ -45,7 +45,7 @@ class BuildCreativeResponse(RootModel[BuildCreativeResponse1 | BuildCreativeResp root: Annotated[ BuildCreativeResponse1 | BuildCreativeResponse2, Field( - description='Response containing the transformed or generated creative manifest, ready for use with preview_creative or sync_creatives. Returns either the complete creative manifest OR error information, never both.', - title='Build Creative Response', + description="Response containing the transformed or generated creative manifest, ready for use with preview_creative or sync_creatives. Returns either the complete creative manifest OR error information, never both.", + title="Build Creative Response", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py index 9c88a3b4..25aa1d52 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_input_required.py @@ -16,22 +16,22 @@ class Reason(Enum): - APPROVAL_REQUIRED = 'APPROVAL_REQUIRED' - BUDGET_EXCEEDS_LIMIT = 'BUDGET_EXCEEDS_LIMIT' + APPROVAL_REQUIRED = "APPROVAL_REQUIRED" + BUDGET_EXCEEDS_LIMIT = "BUDGET_EXCEEDS_LIMIT" class CreateMediaBuyInputRequired(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error] | None, Field( - description='Optional validation errors or warnings for debugging purposes. Helps explain why input is required.' + description="Optional validation errors or warnings for debugging purposes. Helps explain why input is required." ), ] = None ext: ext_1.ExtensionObject | None = None reason: Annotated[ - Reason | None, Field(description='Reason code indicating why input is needed') + Reason | None, Field(description="Reason code indicating why input is needed") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py index 17cb9042..6088ea7e 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_submitted.py @@ -13,7 +13,7 @@ class CreateMediaBuySubmitted(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py index 1c2b2e33..7950a1fa 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_async_response_working.py @@ -15,17 +15,17 @@ class CreateMediaBuyWorking(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None current_step: Annotated[ - str | None, Field(description='Current step or phase of the operation') + str | None, Field(description="Current step or phase of the operation") ] = None ext: ext_1.ExtensionObject | None = None percentage: Annotated[ - float | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0) + float | None, Field(description="Completion percentage (0-100)", ge=0.0, le=100.0) ] = None - step_number: Annotated[int | None, Field(description='Current step number', ge=1)] = None + step_number: Annotated[int | None, Field(description="Current step number", ge=1)] = None total_steps: Annotated[ - int | None, Field(description='Total number of steps in the operation', ge=1) + int | None, Field(description="Total number of steps in the operation", ge=1) ] = None diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py index 13830aba..6a68ec83 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_request.py @@ -20,12 +20,12 @@ class Authentication(AdCPBaseModel): model_config = ConfigDict( - extra='forbid', + extra="forbid", ) credentials: Annotated[ str, Field( - description='Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.', + description="Credentials for authentication. For Bearer: token sent in Authorization header. For HMAC-SHA256: shared secret used to generate signature. Minimum 32 characters. Exchanged out-of-band during onboarding.", min_length=32, ), ] @@ -40,35 +40,35 @@ class Authentication(AdCPBaseModel): class ReportingFrequency(Enum): - hourly = 'hourly' - daily = 'daily' - monthly = 'monthly' + hourly = "hourly" + daily = "daily" + monthly = "monthly" class RequestedMetric(Enum): - impressions = 'impressions' - spend = 'spend' - clicks = 'clicks' - ctr = 'ctr' - video_completions = 'video_completions' - completion_rate = 'completion_rate' - conversions = 'conversions' - viewability = 'viewability' - engagement_rate = 'engagement_rate' + impressions = "impressions" + spend = "spend" + clicks = "clicks" + ctr = "ctr" + video_completions = "video_completions" + completion_rate = "completion_rate" + conversions = "conversions" + viewability = "viewability" + engagement_rate = "engagement_rate" class ReportingWebhook(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) authentication: Annotated[ Authentication, - Field(description='Authentication configuration for webhook delivery (A2A-compatible)'), + Field(description="Authentication configuration for webhook delivery (A2A-compatible)"), ] reporting_frequency: Annotated[ ReportingFrequency, Field( - description='Frequency for automated reporting delivery. Must be supported by all products in the media buy.' + description="Frequency for automated reporting delivery. Must be supported by all products in the media buy." ), ] requested_metrics: Annotated[ @@ -80,37 +80,37 @@ class ReportingWebhook(AdCPBaseModel): token: Annotated[ str | None, Field( - description='Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.', + description="Optional client-provided token for webhook validation. Echoed back in webhook payload to validate request authenticity.", min_length=16, ), ] = None - url: Annotated[AnyUrl, Field(description='Webhook endpoint URL for reporting notifications')] + url: Annotated[AnyUrl, Field(description="Webhook endpoint URL for reporting notifications")] class CreateMediaBuyRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) brand_manifest: Annotated[ brand_manifest_ref.BrandManifestReference, Field( - description='Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests.' + description="Brand information manifest serving as the namespace and identity for this media buy. Provides brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest. Can be cached and reused across multiple requests." ), ] buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this media buy")] context: context_1.ContextObject | None = None end_time: Annotated[ - AwareDatetime, Field(description='Campaign end date/time in ISO 8601 format') + AwareDatetime, Field(description="Campaign end date/time in ISO 8601 format") ] ext: ext_1.ExtensionObject | None = None packages: Annotated[ - list[package_request.PackageRequest], Field(description='Array of package configurations') + list[package_request.PackageRequest], Field(description="Array of package configurations") ] - po_number: Annotated[str | None, Field(description='Purchase order number for tracking')] = None + po_number: Annotated[str | None, Field(description="Purchase order number for tracking")] = None reporting_webhook: Annotated[ ReportingWebhook | None, Field( - description='Optional webhook configuration for automated reporting delivery. Combines push_notification_config structure with reporting-specific fields.' + description="Optional webhook configuration for automated reporting delivery. Combines push_notification_config structure with reporting-specific fields." ), ] = None start_time: start_timing.StartTiming diff --git a/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py b/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py index 3e6b59cd..b2419451 100644 --- a/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py +++ b/src/adcp/types/generated_poc/media_buy/create_media_buy_response.py @@ -17,24 +17,24 @@ class CreateMediaBuyResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], - Field(description='Array of errors explaining why the operation failed', min_length=1), + Field(description="Array of errors explaining why the operation failed", min_length=1), ] ext: ext_1.ExtensionObject | None = None class CreateMediaBuyResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for this media buy")] context: context_1.ContextObject | None = None creative_deadline: Annotated[ - AwareDatetime | None, Field(description='ISO 8601 timestamp for creative upload deadline') + AwareDatetime | None, Field(description="ISO 8601 timestamp for creative upload deadline") ] = None ext: ext_1.ExtensionObject | None = None media_buy_id: Annotated[ @@ -42,7 +42,7 @@ class CreateMediaBuyResponse1(AdCPBaseModel): ] packages: Annotated[ list[package.Package], - Field(description='Array of created packages with complete state information'), + Field(description="Array of created packages with complete state information"), ] @@ -50,7 +50,7 @@ class CreateMediaBuyResponse(RootModel[CreateMediaBuyResponse1 | CreateMediaBuyR root: Annotated[ CreateMediaBuyResponse1 | CreateMediaBuyResponse2, Field( - description='Response payload for create_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - the media buy is either fully created or not created at all.', - title='Create Media Buy Response', + description="Response payload for create_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - the media buy is either fully created or not created at all.", + title="Create Media Buy Response", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py index ba67080d..f293aae9 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py @@ -16,32 +16,32 @@ class GetMediaBuyDeliveryRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_refs: Annotated[ - list[str] | None, Field(description='Array of buyer reference IDs to get delivery data for') + list[str] | None, Field(description="Array of buyer reference IDs to get delivery data for") ] = None context: context_1.ContextObject | None = None end_date: Annotated[ str | None, Field( - description='End date for reporting period (YYYY-MM-DD)', - pattern='^\\d{4}-\\d{2}-\\d{2}$', + description="End date for reporting period (YYYY-MM-DD)", + pattern="^\\d{4}-\\d{2}-\\d{2}$", ), ] = None ext: ext_1.ExtensionObject | None = None media_buy_ids: Annotated[ list[str] | None, - Field(description='Array of publisher media buy IDs to get delivery data for'), + Field(description="Array of publisher media buy IDs to get delivery data for"), ] = None start_date: Annotated[ str | None, Field( - description='Start date for reporting period (YYYY-MM-DD)', - pattern='^\\d{4}-\\d{2}-\\d{2}$', + description="Start date for reporting period (YYYY-MM-DD)", + pattern="^\\d{4}-\\d{2}-\\d{2}$", ), ] = None status_filter: Annotated[ media_buy_status.MediaBuyStatus | list[media_buy_status.MediaBuyStatus] | None, - Field(description='Filter by status. Can be a single status or array of statuses'), + Field(description="Filter by status. Can be a single status or array of statuses"), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py index 467ecaa0..b4e662b6 100644 --- a/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py @@ -19,49 +19,49 @@ class AggregatedTotals(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) clicks: Annotated[ float | None, - Field(description='Total clicks across all media buys (if applicable)', ge=0.0), + Field(description="Total clicks across all media buys (if applicable)", ge=0.0), ] = None impressions: Annotated[ - float, Field(description='Total impressions delivered across all media buys', ge=0.0) + float, Field(description="Total impressions delivered across all media buys", ge=0.0) ] media_buy_count: Annotated[ - int, Field(description='Number of media buys included in the response', ge=0) + int, Field(description="Number of media buys included in the response", ge=0) ] - spend: Annotated[float, Field(description='Total amount spent across all media buys', ge=0.0)] + spend: Annotated[float, Field(description="Total amount spent across all media buys", ge=0.0)] video_completions: Annotated[ float | None, - Field(description='Total video completions across all media buys (if applicable)', ge=0.0), + Field(description="Total video completions across all media buys (if applicable)", ge=0.0), ] = None class DeliveryStatus(Enum): - delivering = 'delivering' - completed = 'completed' - budget_exhausted = 'budget_exhausted' - flight_ended = 'flight_ended' - goal_met = 'goal_met' + delivering = "delivering" + completed = "completed" + budget_exhausted = "budget_exhausted" + flight_ended = "flight_ended" + goal_met = "goal_met" class DailyBreakdownItem(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - date: Annotated[str, Field(description='Date (YYYY-MM-DD)', pattern='^\\d{4}-\\d{2}-\\d{2}$')] - impressions: Annotated[float, Field(description='Daily impressions', ge=0.0)] - spend: Annotated[float, Field(description='Daily spend', ge=0.0)] + date: Annotated[str, Field(description="Date (YYYY-MM-DD)", pattern="^\\d{4}-\\d{2}-\\d{2}$")] + impressions: Annotated[float, Field(description="Daily impressions", ge=0.0)] + spend: Annotated[float, Field(description="Daily spend", ge=0.0)] class Status(Enum): - pending = 'pending' - active = 'active' - paused = 'paused' - completed = 'completed' - failed = 'failed' - reporting_delayed = 'reporting_delayed' + pending = "pending" + active = "active" + paused = "paused" + completed = "completed" + failed = "failed" + reporting_delayed = "reporting_delayed" class Totals(DeliveryMetrics): @@ -76,23 +76,23 @@ class Totals(DeliveryMetrics): class NotificationType(Enum): - scheduled = 'scheduled' - final = 'final' - delayed = 'delayed' - adjusted = 'adjusted' + scheduled = "scheduled" + final = "final" + delayed = "delayed" + adjusted = "adjusted" class ReportingPeriod(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) end: Annotated[ AwareDatetime, - Field(description='ISO 8601 end timestamp in UTC (e.g., 2024-02-05T23:59:59Z)'), + Field(description="ISO 8601 end timestamp in UTC (e.g., 2024-02-05T23:59:59Z)"), ] start: Annotated[ AwareDatetime, - Field(description='ISO 8601 start timestamp in UTC (e.g., 2024-02-05T00:00:00Z)'), + Field(description="ISO 8601 start timestamp in UTC (e.g., 2024-02-05T00:00:00Z)"), ] @@ -104,33 +104,33 @@ class ByPackageItem(DeliveryMetrics): str, Field( description="ISO 4217 currency code (e.g., USD, EUR, GBP) for this package's pricing. Indicates the currency in which the rate and spend values are denominated. Different packages can use different currencies when supported by the publisher.", - pattern='^[A-Z]{3}$', + pattern="^[A-Z]{3}$", ), ] delivery_status: Annotated[ DeliveryStatus | None, Field( - description='System-reported operational state of this package. Reflects actual delivery state independent of buyer pause control.' + description="System-reported operational state of this package. Reflects actual delivery state independent of buyer pause control." ), ] = None pacing_index: Annotated[ float | None, - Field(description='Delivery pace (1.0 = on track, <1.0 = behind, >1.0 = ahead)', ge=0.0), + Field(description="Delivery pace (1.0 = on track, <1.0 = behind, >1.0 = ahead)", ge=0.0), ] = None package_id: Annotated[str, Field(description="Publisher's package identifier")] paused: Annotated[ - bool | None, Field(description='Whether this package is currently paused by the buyer') + bool | None, Field(description="Whether this package is currently paused by the buyer") ] = None pricing_model: Annotated[ pricing_model_1.PricingModel, Field( - description='The pricing model used for this package (e.g., cpm, cpcv, cpp). Indicates how the package is billed and which metrics are most relevant for optimization.' + description="The pricing model used for this package (e.g., cpm, cpcv, cpp). Indicates how the package is billed and which metrics are most relevant for optimization." ), ] rate: Annotated[ float, Field( - description='The pricing rate for this package in the specified currency. For fixed-rate pricing, this is the agreed rate (e.g., CPM rate of 12.50 means $12.50 per 1,000 impressions). For auction-based pricing, this represents the effective rate based on actual delivery.', + description="The pricing rate for this package in the specified currency. For fixed-rate pricing, this is the agreed rate (e.g., CPM rate of 12.50 means $12.50 per 1,000 impressions). For auction-based pricing, this represents the effective rate based on actual delivery.", ge=0.0, ), ] @@ -139,36 +139,36 @@ class ByPackageItem(DeliveryMetrics): class MediaBuyDelivery(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[ str | None, Field(description="Buyer's reference identifier for this media buy") ] = None - by_package: Annotated[list[ByPackageItem], Field(description='Metrics broken down by package')] + by_package: Annotated[list[ByPackageItem], Field(description="Metrics broken down by package")] daily_breakdown: Annotated[ - list[DailyBreakdownItem] | None, Field(description='Day-by-day delivery') + list[DailyBreakdownItem] | None, Field(description="Day-by-day delivery") ] = None expected_availability: Annotated[ AwareDatetime | None, Field( - description='When delayed data is expected to be available (only present when status is reporting_delayed)' + description="When delayed data is expected to be available (only present when status is reporting_delayed)" ), ] = None is_adjusted: Annotated[ bool | None, Field( - description='Indicates this delivery contains updated data for a previously reported period. Buyer should replace previous period data with these totals.' + description="Indicates this delivery contains updated data for a previously reported period. Buyer should replace previous period data with these totals." ), ] = None media_buy_id: Annotated[str, Field(description="Publisher's media buy identifier")] pricing_model: Annotated[ pricing_model_1.PricingModel | None, - Field(description='Pricing model used for this media buy'), + Field(description="Pricing model used for this media buy"), ] = None status: Annotated[ Status, Field( - description='Current media buy status. In webhook context, reporting_delayed indicates data temporarily unavailable.' + description="Current media buy status. In webhook context, reporting_delayed indicates data temporarily unavailable." ), ] totals: Totals @@ -176,27 +176,27 @@ class MediaBuyDelivery(AdCPBaseModel): class GetMediaBuyDeliveryResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) aggregated_totals: Annotated[ AggregatedTotals | None, Field( - description='Combined metrics across all returned media buys. Only included in API responses (get_media_buy_delivery), not in webhook notifications.' + description="Combined metrics across all returned media buys. Only included in API responses (get_media_buy_delivery), not in webhook notifications." ), ] = None context: context_1.ContextObject | None = None - currency: Annotated[str, Field(description='ISO 4217 currency code', pattern='^[A-Z]{3}$')] + currency: Annotated[str, Field(description="ISO 4217 currency code", pattern="^[A-Z]{3}$")] errors: Annotated[ list[error.Error] | None, Field( - description='Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)' + description="Task-specific errors and warnings (e.g., missing delivery data, reporting platform issues)" ), ] = None ext: ext_1.ExtensionObject | None = None media_buy_deliveries: Annotated[ list[MediaBuyDelivery], Field( - description='Array of delivery data for media buys. When used in webhook notifications, may contain multiple media buys aggregated by publisher. When used in get_media_buy_delivery API responses, typically contains requested media buys.' + description="Array of delivery data for media buys. When used in webhook notifications, may contain multiple media buys aggregated by publisher. When used in get_media_buy_delivery API responses, typically contains requested media buys." ), ] next_expected_at: Annotated[ @@ -208,30 +208,30 @@ class GetMediaBuyDeliveryResponse(AdCPBaseModel): notification_type: Annotated[ NotificationType | None, Field( - description='Type of webhook notification (only present in webhook deliveries): scheduled = regular periodic update, final = campaign completed, delayed = data not yet available, adjusted = resending period with updated data' + description="Type of webhook notification (only present in webhook deliveries): scheduled = regular periodic update, final = campaign completed, delayed = data not yet available, adjusted = resending period with updated data" ), ] = None partial_data: Annotated[ bool | None, Field( - description='Indicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)' + description="Indicates if any media buys in this webhook have missing/delayed data (only present in webhook deliveries)" ), ] = None reporting_period: Annotated[ ReportingPeriod, - Field(description='Date range for the report. All periods use UTC timezone.'), + Field(description="Date range for the report. All periods use UTC timezone."), ] sequence_number: Annotated[ int | None, Field( - description='Sequential notification number (only present in webhook deliveries, starts at 1)', + description="Sequential notification number (only present in webhook deliveries, starts at 1)", ge=1, ), ] = None unavailable_count: Annotated[ int | None, Field( - description='Number of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)', + description="Number of media buys with reporting_delayed or failed status (only present in webhook deliveries when partial_data is true)", ge=0, ), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py index 3bf2f2e4..c3b45976 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_input_required.py @@ -16,23 +16,23 @@ class Reason(Enum): - CLARIFICATION_NEEDED = 'CLARIFICATION_NEEDED' - BUDGET_REQUIRED = 'BUDGET_REQUIRED' + CLARIFICATION_NEEDED = "CLARIFICATION_NEEDED" + BUDGET_REQUIRED = "BUDGET_REQUIRED" class GetProductsInputRequired(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None partial_results: Annotated[ list[product.Product] | None, - Field(description='Partial product results that may help inform the clarification'), + Field(description="Partial product results that may help inform the clarification"), ] = None reason: Annotated[ - Reason | None, Field(description='Reason code indicating why input is needed') + Reason | None, Field(description="Reason code indicating why input is needed") ] = None suggestions: Annotated[ - list[str] | None, Field(description='Suggested values or options for the required input') + list[str] | None, Field(description="Suggested values or options for the required input") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py index 2502b663..b00a379f 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_submitted.py @@ -15,10 +15,10 @@ class GetProductsSubmitted(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None estimated_completion: Annotated[ - AwareDatetime | None, Field(description='Estimated completion time for the search') + AwareDatetime | None, Field(description="Estimated completion time for the search") ] = None ext: ext_1.ExtensionObject | None = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py b/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py index 07d1b15f..f3d7d1eb 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_async_response_working.py @@ -15,7 +15,7 @@ class GetProductsWorking(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None current_step: Annotated[ @@ -27,9 +27,9 @@ class GetProductsWorking(AdCPBaseModel): ext: ext_1.ExtensionObject | None = None percentage: Annotated[ float | None, - Field(description='Progress percentage of the search operation', ge=0.0, le=100.0), + Field(description="Progress percentage of the search operation", ge=0.0, le=100.0), ] = None - step_number: Annotated[int | None, Field(description='Current step number (1-indexed)')] = None + step_number: Annotated[int | None, Field(description="Current step number (1-indexed)")] = None total_steps: Annotated[ - int | None, Field(description='Total number of steps in the search process') + int | None, Field(description="Total number of steps in the search process") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_request.py b/src/adcp/types/generated_poc/media_buy/get_products_request.py index aaf469c7..7b56d5dc 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_request.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_request.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -12,22 +12,28 @@ from ..core import brand_manifest_ref from ..core import context as context_1 from ..core import ext as ext_1 -from ..core import product_filters +from ..core import product_filters, property_list_ref class GetProductsRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) brand_manifest: Annotated[ brand_manifest_ref.BrandManifestReference | None, Field( - description='Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest.' + description="Brand information manifest providing brand context, assets, and product catalog. Can be provided inline or as a URL reference to a hosted manifest." ), ] = None brief: Annotated[ - str | None, Field(description='Natural language description of campaign requirements') + str | None, Field(description="Natural language description of campaign requirements") ] = None context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None filters: product_filters.ProductFilters | None = None + property_list: Annotated[ + property_list_ref.PropertyListReference | None, + Field( + description="[AdCP 3.0] Reference to an externally managed property list. When provided, the sales agent should filter products to only those available on properties in the list." + ), + ] = None diff --git a/src/adcp/types/generated_poc/media_buy/get_products_response.py b/src/adcp/types/generated_poc/media_buy/get_products_response.py index 7e9fb071..91c11e17 100644 --- a/src/adcp/types/generated_poc/media_buy/get_products_response.py +++ b/src/adcp/types/generated_poc/media_buy/get_products_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/get_products_response.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -17,12 +17,18 @@ class GetProductsResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error] | None, - Field(description='Task-specific errors and warnings (e.g., product filtering issues)'), + Field(description="Task-specific errors and warnings (e.g., product filtering issues)"), ] = None ext: ext_1.ExtensionObject | None = None - products: Annotated[list[product.Product], Field(description='Array of matching products')] + products: Annotated[list[product.Product], Field(description="Array of matching products")] + property_list_applied: Annotated[ + bool | None, + Field( + description="[AdCP 3.0] Indicates whether property_list filtering was applied. True if the agent filtered products based on the provided property_list. Absent or false if property_list was not provided or not supported by this agent." + ), + ] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_authorized_properties_request.py b/src/adcp/types/generated_poc/media_buy/list_authorized_properties_request.py index a0b495ea..3f97a866 100644 --- a/src/adcp/types/generated_poc/media_buy/list_authorized_properties_request.py +++ b/src/adcp/types/generated_poc/media_buy/list_authorized_properties_request.py @@ -18,21 +18,21 @@ class PublisherDomain(RootModel[str]): str, Field( description="Publisher domain to filter by (e.g., 'cnn.com', 'espn.com')", - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] class ListAuthorizedPropertiesRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None publisher_domains: Annotated[ list[PublisherDomain] | None, Field( - description='Filter to specific publisher domains (optional). If omitted, returns all publishers this agent represents.', + description="Filter to specific publisher domains (optional). If omitted, returns all publishers this agent represents.", min_length=1, ), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_authorized_properties_response.py b/src/adcp/types/generated_poc/media_buy/list_authorized_properties_response.py index e5e8cb3d..ad30e66e 100644 --- a/src/adcp/types/generated_poc/media_buy/list_authorized_properties_response.py +++ b/src/adcp/types/generated_poc/media_buy/list_authorized_properties_response.py @@ -16,7 +16,7 @@ class PrimaryCountry(RootModel[str]): - root: Annotated[str, Field(pattern='^[A-Z]{2}$')] + root: Annotated[str, Field(pattern="^[A-Z]{2}$")] class PublisherDomain(RootModel[str]): @@ -24,14 +24,14 @@ class PublisherDomain(RootModel[str]): str, Field( description="Domain where publisher's adagents.json is hosted (e.g., 'cnn.com')", - pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", ), ] class ListAuthorizedPropertiesResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) advertising_policies: Annotated[ str | None, @@ -44,7 +44,7 @@ class ListAuthorizedPropertiesResponse(AdCPBaseModel): context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error] | None, - Field(description='Task-specific errors and warnings (e.g., property availability issues)'), + Field(description="Task-specific errors and warnings (e.g., property availability issues)"), ] = None ext: ext_1.ExtensionObject | None = None last_updated: Annotated[ @@ -56,7 +56,7 @@ class ListAuthorizedPropertiesResponse(AdCPBaseModel): portfolio_description: Annotated[ str | None, Field( - description='Markdown-formatted description of the property portfolio, including inventory types, audience characteristics, and special features.', + description="Markdown-formatted description of the property portfolio, including inventory types, audience characteristics, and special features.", max_length=5000, min_length=1, ), @@ -64,14 +64,14 @@ class ListAuthorizedPropertiesResponse(AdCPBaseModel): primary_channels: Annotated[ list[channels.AdvertisingChannels] | None, Field( - description='Primary advertising channels represented in this property portfolio. Helps buying agents quickly filter relevance.', + description="Primary advertising channels represented in this property portfolio. Helps buying agents quickly filter relevance.", min_length=1, ), ] = None primary_countries: Annotated[ list[PrimaryCountry] | None, Field( - description='Primary countries (ISO 3166-1 alpha-2 codes) where properties are concentrated. Helps buying agents quickly filter relevance.', + description="Primary countries (ISO 3166-1 alpha-2 codes) where properties are concentrated. Helps buying agents quickly filter relevance.", min_length=1, ), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py b/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py index d50b4f66..89eb0639 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/media_buy/list_creative_formats_request.py @@ -17,7 +17,7 @@ class ListCreativeFormatsRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) asset_types: Annotated[ list[asset_content_type.AssetContentType] | None, @@ -30,45 +30,45 @@ class ListCreativeFormatsRequest(AdCPBaseModel): format_ids: Annotated[ list[format_id.FormatId] | None, Field( - description='Return only these specific format IDs (e.g., from get_products response)' + description="Return only these specific format IDs (e.g., from get_products response)" ), ] = None is_responsive: Annotated[ bool | None, Field( - description='Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions.' + description="Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions." ), ] = None max_height: Annotated[ int | None, Field( - description='Maximum height in pixels (inclusive). Returns formats where ANY render has height <= this value. For multi-render formats, matches if at least one render fits.' + description="Maximum height in pixels (inclusive). Returns formats where ANY render has height <= this value. For multi-render formats, matches if at least one render fits." ), ] = None max_width: Annotated[ int | None, Field( - description='Maximum width in pixels (inclusive). Returns formats where ANY render has width <= this value. For multi-render formats, matches if at least one render fits.' + description="Maximum width in pixels (inclusive). Returns formats where ANY render has width <= this value. For multi-render formats, matches if at least one render fits." ), ] = None min_height: Annotated[ int | None, Field( - description='Minimum height in pixels (inclusive). Returns formats where ANY render has height >= this value.' + description="Minimum height in pixels (inclusive). Returns formats where ANY render has height >= this value." ), ] = None min_width: Annotated[ int | None, Field( - description='Minimum width in pixels (inclusive). Returns formats where ANY render has width >= this value.' + description="Minimum width in pixels (inclusive). Returns formats where ANY render has width >= this value." ), ] = None name_search: Annotated[ - str | None, Field(description='Search for formats by name (case-insensitive partial match)') + str | None, Field(description="Search for formats by name (case-insensitive partial match)") ] = None type: Annotated[ format_category.FormatCategory | None, Field( - description='Filter by format type (technical categories with distinct requirements)' + description="Filter by format type (technical categories with distinct requirements)" ), ] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py b/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py index e60933f4..cc791a14 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py +++ b/src/adcp/types/generated_poc/media_buy/list_creative_formats_response.py @@ -18,7 +18,7 @@ class CreativeAgent(AdCPBaseModel): agent_name: Annotated[ - str | None, Field(description='Human-readable name for the creative agent') + str | None, Field(description="Human-readable name for the creative agent") ] = None agent_url: Annotated[ AnyUrl, @@ -28,24 +28,24 @@ class CreativeAgent(AdCPBaseModel): ] capabilities: Annotated[ list[creative_agent_capability.CreativeAgentCapability] | None, - Field(description='Capabilities this creative agent provides'), + Field(description="Capabilities this creative agent provides"), ] = None class ListCreativeFormatsResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creative_agents: Annotated[ list[CreativeAgent] | None, Field( - description='Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats.' + description="Optional: Creative agents that provide additional formats. Buyers can recursively query these agents to discover more formats. No authentication required for list_creative_formats." ), ] = None errors: Annotated[ list[error.Error] | None, - Field(description='Task-specific errors and warnings (e.g., format availability issues)'), + Field(description="Task-specific errors and warnings (e.g., format availability issues)"), ] = None ext: ext_1.ExtensionObject | None = None formats: Annotated[ diff --git a/src/adcp/types/generated_poc/media_buy/list_creatives_request.py b/src/adcp/types/generated_poc/media_buy/list_creatives_request.py index 8438d252..e855347b 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creatives_request.py +++ b/src/adcp/types/generated_poc/media_buy/list_creatives_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/list_creatives_request.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -17,60 +17,60 @@ class FieldModel(Enum): - creative_id = 'creative_id' - name = 'name' - format = 'format' - status = 'status' - created_date = 'created_date' - updated_date = 'updated_date' - tags = 'tags' - assignments = 'assignments' - performance = 'performance' - sub_assets = 'sub_assets' + creative_id = "creative_id" + name = "name" + format = "format" + status = "status" + created_date = "created_date" + updated_date = "updated_date" + tags = "tags" + assignments = "assignments" + performance = "performance" + sub_assets = "sub_assets" class Pagination(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) limit: Annotated[ - int | None, Field(description='Maximum number of creatives to return', ge=1, le=100) + int | None, Field(description="Maximum number of creatives to return", ge=1, le=100) ] = 50 - offset: Annotated[int | None, Field(description='Number of creatives to skip', ge=0)] = 0 + offset: Annotated[int | None, Field(description="Number of creatives to skip", ge=0)] = 0 class Sort(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) direction: Annotated[ - sort_direction.SortDirection | None, Field(description='Sort direction') + sort_direction.SortDirection | None, Field(description="Sort direction") ] = sort_direction.SortDirection.desc field: Annotated[ - creative_sort_field.CreativeSortField | None, Field(description='Field to sort by') + creative_sort_field.CreativeSortField | None, Field(description="Field to sort by") ] = creative_sort_field.CreativeSortField.created_date class ListCreativesRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None fields: Annotated[ list[FieldModel] | None, - Field(description='Specific fields to include in response (omit for all fields)'), + Field(description="Specific fields to include in response (omit for all fields)"), ] = None filters: creative_filters.CreativeFilters | None = None include_assignments: Annotated[ - bool | None, Field(description='Include package assignment information in response') + bool | None, Field(description="Include package assignment information in response") ] = True include_performance: Annotated[ - bool | None, Field(description='Include aggregated performance metrics in response') + bool | None, Field(description="Include aggregated performance metrics in response") ] = False include_sub_assets: Annotated[ bool | None, - Field(description='Include sub-assets (for carousel/native formats) in response'), + Field(description="Include sub-assets (for carousel/native formats) in response"), ] = False - pagination: Annotated[Pagination | None, Field(description='Pagination parameters')] = None - sort: Annotated[Sort | None, Field(description='Sorting parameters')] = None + pagination: Annotated[Pagination | None, Field(description="Pagination parameters")] = None + sort: Annotated[Sort | None, Field(description="Sorting parameters")] = None diff --git a/src/adcp/types/generated_poc/media_buy/list_creatives_response.py b/src/adcp/types/generated_poc/media_buy/list_creatives_response.py index c1dc2cfe..50b713dc 100644 --- a/src/adcp/types/generated_poc/media_buy/list_creatives_response.py +++ b/src/adcp/types/generated_poc/media_buy/list_creatives_response.py @@ -30,83 +30,83 @@ class Status(Enum): - active = 'active' - paused = 'paused' - ended = 'ended' + active = "active" + paused = "paused" + ended = "ended" class AssignedPackage(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - assigned_date: Annotated[AwareDatetime, Field(description='When this assignment was created')] - package_id: Annotated[str, Field(description='Package identifier')] - package_name: Annotated[str | None, Field(description='Human-readable package name')] = None - status: Annotated[Status, Field(description='Status of this specific assignment')] + assigned_date: Annotated[AwareDatetime, Field(description="When this assignment was created")] + package_id: Annotated[str, Field(description="Package identifier")] + package_name: Annotated[str | None, Field(description="Human-readable package name")] = None + status: Annotated[Status, Field(description="Status of this specific assignment")] class Assignments(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assigned_packages: Annotated[ list[AssignedPackage] | None, - Field(description='List of packages this creative is assigned to'), + Field(description="List of packages this creative is assigned to"), ] = None assignment_count: Annotated[ - int, Field(description='Total number of active package assignments', ge=0) + int, Field(description="Total number of active package assignments", ge=0) ] class Performance(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) clicks: Annotated[ - int | None, Field(description='Total clicks across all assignments', ge=0) + int | None, Field(description="Total clicks across all assignments", ge=0) ] = None conversion_rate: Annotated[ - float | None, Field(description='Conversion rate across all assignments', ge=0.0, le=1.0) + float | None, Field(description="Conversion rate across all assignments", ge=0.0, le=1.0) ] = None ctr: Annotated[ - float | None, Field(description='Click-through rate (clicks/impressions)', ge=0.0, le=1.0) + float | None, Field(description="Click-through rate (clicks/impressions)", ge=0.0, le=1.0) ] = None impressions: Annotated[ - int | None, Field(description='Total impressions across all assignments', ge=0) + int | None, Field(description="Total impressions across all assignments", ge=0) ] = None last_updated: Annotated[ - AwareDatetime, Field(description='When performance data was last updated') + AwareDatetime, Field(description="When performance data was last updated") ] performance_score: Annotated[ - float | None, Field(description='Aggregated performance score (0-100)', ge=0.0, le=100.0) + float | None, Field(description="Aggregated performance score (0-100)", ge=0.0, le=100.0) ] = None class Pagination(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) current_page: Annotated[ - int | None, Field(description='Current page number (1-based)', ge=1) + int | None, Field(description="Current page number (1-based)", ge=1) ] = None - has_more: Annotated[bool, Field(description='Whether more results are available')] - limit: Annotated[int, Field(description='Maximum number of results requested', ge=1)] - offset: Annotated[int, Field(description='Number of results skipped', ge=0)] + has_more: Annotated[bool, Field(description="Whether more results are available")] + limit: Annotated[int, Field(description="Maximum number of results requested", ge=1)] + offset: Annotated[int, Field(description="Number of results skipped", ge=0)] total_pages: Annotated[ - int | None, Field(description='Total number of pages available', ge=0) + int | None, Field(description="Total number of pages available", ge=0) ] = None class StatusSummary(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - approved: Annotated[int | None, Field(description='Number of approved creatives', ge=0)] = None - archived: Annotated[int | None, Field(description='Number of archived creatives', ge=0)] = None + approved: Annotated[int | None, Field(description="Number of approved creatives", ge=0)] = None + archived: Annotated[int | None, Field(description="Number of archived creatives", ge=0)] = None pending_review: Annotated[ - int | None, Field(description='Number of creatives pending review', ge=0) + int | None, Field(description="Number of creatives pending review", ge=0) ] = None - rejected: Annotated[int | None, Field(description='Number of rejected creatives', ge=0)] = None + rejected: Annotated[int | None, Field(description="Number of rejected creatives", ge=0)] = None class SortApplied(AdCPBaseModel): @@ -116,26 +116,26 @@ class SortApplied(AdCPBaseModel): class QuerySummary(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) filters_applied: Annotated[ - list[str] | None, Field(description='List of filters that were applied to the query') + list[str] | None, Field(description="List of filters that were applied to the query") ] = None returned: Annotated[ - int, Field(description='Number of creatives returned in this response', ge=0) + int, Field(description="Number of creatives returned in this response", ge=0) ] sort_applied: Annotated[ - SortApplied | None, Field(description='Sort order that was applied') + SortApplied | None, Field(description="Sort order that was applied") ] = None total_matching: Annotated[ int, - Field(description='Total number of creatives matching filters (across all pages)', ge=0), + Field(description="Total number of creatives matching filters (across all pages)", ge=0), ] class Creative(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assets: Annotated[ dict[ @@ -153,60 +153,60 @@ class Creative(AdCPBaseModel): | url_asset.UrlAsset, ] | None, - Field(description='Assets for this creative, keyed by asset_role'), + Field(description="Assets for this creative, keyed by asset_role"), ] = None assignments: Annotated[ Assignments | None, - Field(description='Current package assignments (included when include_assignments=true)'), + Field(description="Current package assignments (included when include_assignments=true)"), ] = None created_date: Annotated[ - AwareDatetime, Field(description='When the creative was uploaded to the library') + AwareDatetime, Field(description="When the creative was uploaded to the library") ] - creative_id: Annotated[str, Field(description='Unique identifier for the creative')] + creative_id: Annotated[str, Field(description="Unique identifier for the creative")] format_id: Annotated[ format_id_1.FormatId, - Field(description='Format identifier specifying which format this creative conforms to'), + Field(description="Format identifier specifying which format this creative conforms to"), ] - name: Annotated[str, Field(description='Human-readable creative name')] + name: Annotated[str, Field(description="Human-readable creative name")] performance: Annotated[ Performance | None, Field( - description='Aggregated performance metrics (included when include_performance=true)' + description="Aggregated performance metrics (included when include_performance=true)" ), ] = None status: Annotated[ - creative_status.CreativeStatus, Field(description='Current approval status of the creative') + creative_status.CreativeStatus, Field(description="Current approval status of the creative") ] sub_assets: Annotated[ list[sub_asset.SubAsset] | None, Field( - description='Sub-assets for multi-asset formats (included when include_sub_assets=true)' + description="Sub-assets for multi-asset formats (included when include_sub_assets=true)" ), ] = None tags: Annotated[ - list[str] | None, Field(description='User-defined tags for organization and searchability') + list[str] | None, Field(description="User-defined tags for organization and searchability") ] = None - updated_date: Annotated[AwareDatetime, Field(description='When the creative was last modified')] + updated_date: Annotated[AwareDatetime, Field(description="When the creative was last modified")] class ListCreativesResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creatives: Annotated[ - list[Creative], Field(description='Array of creative assets matching the query') + list[Creative], Field(description="Array of creative assets matching the query") ] ext: ext_1.ExtensionObject | None = None format_summary: Annotated[ - dict[str, int] | None, Field(description='Breakdown of creatives by format type') + dict[str, int] | None, Field(description="Breakdown of creatives by format type") ] = None pagination: Annotated[ - Pagination, Field(description='Pagination information for navigating results') + Pagination, Field(description="Pagination information for navigating results") ] query_summary: Annotated[ - QuerySummary, Field(description='Summary of the query that was executed') + QuerySummary, Field(description="Summary of the query that was executed") ] status_summary: Annotated[ - StatusSummary | None, Field(description='Breakdown of creatives by status') + StatusSummary | None, Field(description="Breakdown of creatives by status") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/package_request.py b/src/adcp/types/generated_poc/media_buy/package_request.py index 16c64ec6..bfaf96b0 100644 --- a/src/adcp/types/generated_poc/media_buy/package_request.py +++ b/src/adcp/types/generated_poc/media_buy/package_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/package_request.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -17,12 +17,12 @@ class PackageRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bid_price: Annotated[ float | None, Field( - description='Bid price for auction-based CPM pricing (required if using cpm-auction-option)', + description="Bid price for auction-based CPM pricing (required if using cpm-auction-option)", ge=0.0, ), ] = None @@ -34,13 +34,13 @@ class PackageRequest(AdCPBaseModel): creative_ids: Annotated[ list[str] | None, Field( - description='Creative IDs to assign to this package at creation time (references existing library creatives)' + description="Creative IDs to assign to this package at creation time (references existing library creatives)" ), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset] | None, Field( - description='Full creative objects to upload and assign to this package at creation time (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.', + description="Full creative objects to upload and assign to this package at creation time (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.", max_length=100, ), ] = None @@ -48,16 +48,25 @@ class PackageRequest(AdCPBaseModel): format_ids: Annotated[ list[format_id.FormatId] | None, Field( - description='Array of format IDs that will be used for this package - must be supported by the product. If omitted, defaults to all formats supported by the product.', + description="Array of format IDs that will be used for this package - must be supported by the product. If omitted, defaults to all formats supported by the product.", min_length=1, ), ] = None + impressions: Annotated[ + float | None, Field(description="Impression goal for this package", ge=0.0) + ] = None pacing: pacing_1.Pacing | None = None + paused: Annotated[ + bool | None, + Field( + description="Whether this package should be created in a paused state. Paused packages do not deliver impressions. Defaults to false." + ), + ] = False pricing_option_id: Annotated[ str, Field( description="ID of the selected pricing option from the product's pricing_options array" ), ] - product_id: Annotated[str, Field(description='Product ID for this package')] + product_id: Annotated[str, Field(description="Product ID for this package")] targeting_overlay: targeting.TargetingOverlay | None = None diff --git a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py index 0b98f46b..712629b4 100644 --- a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +++ b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py @@ -17,19 +17,19 @@ class MeasurementPeriod(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) end: Annotated[ - AwareDatetime, Field(description='ISO 8601 end timestamp for measurement period') + AwareDatetime, Field(description="ISO 8601 end timestamp for measurement period") ] start: Annotated[ - AwareDatetime, Field(description='ISO 8601 start timestamp for measurement period') + AwareDatetime, Field(description="ISO 8601 start timestamp for measurement period") ] class ProvidePerformanceFeedbackRequest1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[ str | None, Field(description="Buyer's reference for the media buy", min_length=1) @@ -38,33 +38,33 @@ class ProvidePerformanceFeedbackRequest1(AdCPBaseModel): creative_id: Annotated[ str | None, Field( - description='Specific creative asset (if feedback is creative-specific)', min_length=1 + description="Specific creative asset (if feedback is creative-specific)", min_length=1 ), ] = None ext: ext_1.ExtensionObject | None = None feedback_source: Annotated[ - feedback_source_1.FeedbackSource | None, Field(description='Source of the performance data') + feedback_source_1.FeedbackSource | None, Field(description="Source of the performance data") ] = feedback_source_1.FeedbackSource.buyer_attribution measurement_period: Annotated[ - MeasurementPeriod, Field(description='Time period for performance measurement') + MeasurementPeriod, Field(description="Time period for performance measurement") ] media_buy_id: Annotated[ str, Field(description="Publisher's media buy identifier", min_length=1) ] metric_type: Annotated[ - metric_type_1.MetricType | None, Field(description='The business metric being measured') + metric_type_1.MetricType | None, Field(description="The business metric being measured") ] = metric_type_1.MetricType.overall_performance package_id: Annotated[ str | None, Field( - description='Specific package within the media buy (if feedback is package-specific)', + description="Specific package within the media buy (if feedback is package-specific)", min_length=1, ), ] = None performance_index: Annotated[ float, Field( - description='Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)', + description="Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)", ge=0.0, ), ] @@ -72,7 +72,7 @@ class ProvidePerformanceFeedbackRequest1(AdCPBaseModel): class ProvidePerformanceFeedbackRequest2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[ str, Field(description="Buyer's reference for the media buy", min_length=1) @@ -81,33 +81,33 @@ class ProvidePerformanceFeedbackRequest2(AdCPBaseModel): creative_id: Annotated[ str | None, Field( - description='Specific creative asset (if feedback is creative-specific)', min_length=1 + description="Specific creative asset (if feedback is creative-specific)", min_length=1 ), ] = None ext: ext_1.ExtensionObject | None = None feedback_source: Annotated[ - feedback_source_1.FeedbackSource | None, Field(description='Source of the performance data') + feedback_source_1.FeedbackSource | None, Field(description="Source of the performance data") ] = feedback_source_1.FeedbackSource.buyer_attribution measurement_period: Annotated[ - MeasurementPeriod, Field(description='Time period for performance measurement') + MeasurementPeriod, Field(description="Time period for performance measurement") ] media_buy_id: Annotated[ str | None, Field(description="Publisher's media buy identifier", min_length=1) ] = None metric_type: Annotated[ - metric_type_1.MetricType | None, Field(description='The business metric being measured') + metric_type_1.MetricType | None, Field(description="The business metric being measured") ] = metric_type_1.MetricType.overall_performance package_id: Annotated[ str | None, Field( - description='Specific package within the media buy (if feedback is package-specific)', + description="Specific package within the media buy (if feedback is package-specific)", min_length=1, ), ] = None performance_index: Annotated[ float, Field( - description='Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)', + description="Normalized performance score (0.0 = no value, 1.0 = expected, >1.0 = above expected)", ge=0.0, ), ] @@ -119,7 +119,7 @@ class ProvidePerformanceFeedbackRequest( root: Annotated[ ProvidePerformanceFeedbackRequest1 | ProvidePerformanceFeedbackRequest2, Field( - description='Request payload for provide_performance_feedback task', - title='Provide Performance Feedback Request', + description="Request payload for provide_performance_feedback task", + title="Provide Performance Feedback Request", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py index c3d5a782..750b9ad9 100644 --- a/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +++ b/src/adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py @@ -16,25 +16,25 @@ class ProvidePerformanceFeedbackResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None success: Annotated[ Literal[True], - Field(description='Whether the performance feedback was successfully received'), + Field(description="Whether the performance feedback was successfully received"), ] class ProvidePerformanceFeedbackResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], Field( - description='Array of errors explaining why feedback was rejected (e.g., invalid measurement period, missing campaign data)', + description="Array of errors explaining why feedback was rejected (e.g., invalid measurement period, missing campaign data)", min_length=1, ), ] @@ -47,7 +47,7 @@ class ProvidePerformanceFeedbackResponse( root: Annotated[ ProvidePerformanceFeedbackResponse1 | ProvidePerformanceFeedbackResponse2, Field( - description='Response payload for provide_performance_feedback task. Returns either success confirmation OR error information, never both.', - title='Provide Performance Feedback Response', + description="Response payload for provide_performance_feedback task. Returns either success confirmation OR error information, never both.", + title="Provide Performance Feedback Response", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py index 4b07b57a..e6022d68 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_input_required.py @@ -15,17 +15,17 @@ class Reason(Enum): - APPROVAL_REQUIRED = 'APPROVAL_REQUIRED' - ASSET_CONFIRMATION = 'ASSET_CONFIRMATION' - FORMAT_CLARIFICATION = 'FORMAT_CLARIFICATION' + APPROVAL_REQUIRED = "APPROVAL_REQUIRED" + ASSET_CONFIRMATION = "ASSET_CONFIRMATION" + FORMAT_CLARIFICATION = "FORMAT_CLARIFICATION" class SyncCreativesInputRequired(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None reason: Annotated[ - Reason | None, Field(description='Reason code indicating why buyer input is needed') + Reason | None, Field(description="Reason code indicating why buyer input is needed") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py index 6143049e..504c9495 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_submitted.py @@ -13,7 +13,7 @@ class SyncCreativesSubmitted(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py index c37cf5df..b53c2596 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_async_response_working.py @@ -15,23 +15,23 @@ class SyncCreativesWorking(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creatives_processed: Annotated[ - int | None, Field(description='Number of creatives processed so far', ge=0) + int | None, Field(description="Number of creatives processed so far", ge=0) ] = None creatives_total: Annotated[ - int | None, Field(description='Total number of creatives to process', ge=0) + int | None, Field(description="Total number of creatives to process", ge=0) ] = None current_step: Annotated[ - str | None, Field(description='Current step or phase of the operation') + str | None, Field(description="Current step or phase of the operation") ] = None ext: ext_1.ExtensionObject | None = None percentage: Annotated[ - float | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0) + float | None, Field(description="Completion percentage (0-100)", ge=0.0, le=100.0) ] = None - step_number: Annotated[int | None, Field(description='Current step number', ge=1)] = None + step_number: Annotated[int | None, Field(description="Current step number", ge=1)] = None total_steps: Annotated[ - int | None, Field(description='Total number of steps in the operation', ge=1) + int | None, Field(description="Total number of steps in the operation", ge=1) ] = None diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py index 38d1730e..a1655bb5 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_request.py @@ -18,41 +18,41 @@ class SyncCreativesRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) assignments: Annotated[ dict[str, list[str]] | None, - Field(description='Optional bulk assignment of creatives to packages'), + Field(description="Optional bulk assignment of creatives to packages"), ] = None context: context_1.ContextObject | None = None creative_ids: Annotated[ list[str] | None, Field( - description='Optional filter to limit sync scope to specific creative IDs. When provided, only these creatives will be created/updated. Other creatives in the library are unaffected. Useful for partial updates and error recovery.', + description="Optional filter to limit sync scope to specific creative IDs. When provided, only these creatives will be created/updated. Other creatives in the library are unaffected. Useful for partial updates and error recovery.", max_length=100, ), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset], - Field(description='Array of creative assets to sync (create or update)', max_length=100), + Field(description="Array of creative assets to sync (create or update)", max_length=100), ] delete_missing: Annotated[ bool | None, Field( - description='When true, creatives not included in this sync will be archived. Use with caution for full library replacement.' + description="When true, creatives not included in this sync will be archived. Use with caution for full library replacement." ), ] = False dry_run: Annotated[ bool | None, Field( - description='When true, preview changes without applying them. Returns what would be created/updated/deleted.' + description="When true, preview changes without applying them. Returns what would be created/updated/deleted." ), ] = False ext: ext_1.ExtensionObject | None = None push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( - description='Optional webhook configuration for async sync notifications. Publisher will send webhook when sync completes if operation takes longer than immediate response time (typically for large bulk operations or manual approval/HITL).' + description="Optional webhook configuration for async sync notifications. Publisher will send webhook when sync completes if operation takes longer than immediate response time (typically for large bulk operations or manual approval/HITL)." ), ] = None validation_mode: Annotated[ diff --git a/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py b/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py index 62b64ef6..fef20785 100644 --- a/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py +++ b/src/adcp/types/generated_poc/media_buy/sync_creatives_response.py @@ -17,28 +17,28 @@ class Creative(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) action: Annotated[ - creative_action.CreativeAction, Field(description='Action taken for this creative') + creative_action.CreativeAction, Field(description="Action taken for this creative") ] assigned_to: Annotated[ list[str] | None, Field( - description='Package IDs this creative was successfully assigned to (only present when assignments were requested)' + description="Package IDs this creative was successfully assigned to (only present when assignments were requested)" ), ] = None assignment_errors: Annotated[ dict[str, str] | None, Field( - description='Assignment errors by package ID (only present when assignment failures occurred)' + description="Assignment errors by package ID (only present when assignment failures occurred)" ), ] = None changes: Annotated[ list[str] | None, Field(description="Field names that were modified (only present when action='updated')"), ] = None - creative_id: Annotated[str, Field(description='Creative ID from the request')] + creative_id: Annotated[str, Field(description="Creative ID from the request")] errors: Annotated[ list[str] | None, Field(description="Validation or processing errors (only present when action='failed')"), @@ -46,26 +46,26 @@ class Creative(AdCPBaseModel): expires_at: Annotated[ AwareDatetime | None, Field( - description='ISO 8601 timestamp when preview link expires (only present when preview_url exists)' + description="ISO 8601 timestamp when preview link expires (only present when preview_url exists)" ), ] = None platform_id: Annotated[ - str | None, Field(description='Platform-specific ID assigned to the creative') + str | None, Field(description="Platform-specific ID assigned to the creative") ] = None preview_url: Annotated[ AnyUrl | None, Field( - description='Preview URL for generative creatives (only present for generative formats)' + description="Preview URL for generative creatives (only present for generative formats)" ), ] = None warnings: Annotated[ - list[str] | None, Field(description='Non-fatal warnings about this creative') + list[str] | None, Field(description="Non-fatal warnings about this creative") ] = None class SyncCreativesResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None creatives: Annotated[ @@ -75,20 +75,20 @@ class SyncCreativesResponse1(AdCPBaseModel): ), ] dry_run: Annotated[ - bool | None, Field(description='Whether this was a dry run (no actual changes made)') + bool | None, Field(description="Whether this was a dry run (no actual changes made)") ] = None ext: ext_1.ExtensionObject | None = None class SyncCreativesResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], Field( - description='Operation-level errors that prevented processing any creatives (e.g., authentication failure, service unavailable, invalid request format)', + description="Operation-level errors that prevented processing any creatives (e.g., authentication failure, service unavailable, invalid request format)", min_length=1, ), ] @@ -99,7 +99,7 @@ class SyncCreativesResponse(RootModel[SyncCreativesResponse1 | SyncCreativesResp root: Annotated[ SyncCreativesResponse1 | SyncCreativesResponse2, Field( - description='Response from creative sync operation. Returns either per-creative results (best-effort processing) OR operation-level errors (complete failure). This enforces atomic semantics at the operation level while allowing per-item failures within successful operations.', - title='Sync Creatives Response', + description="Response from creative sync operation. Returns either per-creative results (best-effort processing) OR operation-level errors (complete failure). This enforces atomic semantics at the operation level while allowing per-item failures within successful operations.", + title="Sync Creatives Response", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py index 424db645..1e395129 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_input_required.py @@ -15,16 +15,16 @@ class Reason(Enum): - APPROVAL_REQUIRED = 'APPROVAL_REQUIRED' - CHANGE_CONFIRMATION = 'CHANGE_CONFIRMATION' + APPROVAL_REQUIRED = "APPROVAL_REQUIRED" + CHANGE_CONFIRMATION = "CHANGE_CONFIRMATION" class UpdateMediaBuyInputRequired(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None reason: Annotated[ - Reason | None, Field(description='Reason code indicating why input is needed') + Reason | None, Field(description="Reason code indicating why input is needed") ] = None diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py index 406b463b..b2cd67c0 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_submitted.py @@ -13,7 +13,7 @@ class UpdateMediaBuySubmitted(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py index 5d394d51..66f0d102 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_async_response_working.py @@ -15,17 +15,17 @@ class UpdateMediaBuyWorking(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None current_step: Annotated[ - str | None, Field(description='Current step or phase of the operation') + str | None, Field(description="Current step or phase of the operation") ] = None ext: ext_1.ExtensionObject | None = None percentage: Annotated[ - float | None, Field(description='Completion percentage (0-100)', ge=0.0, le=100.0) + float | None, Field(description="Completion percentage (0-100)", ge=0.0, le=100.0) ] = None - step_number: Annotated[int | None, Field(description='Current step number', ge=1)] = None + step_number: Annotated[int | None, Field(description="Current step number", ge=1)] = None total_steps: Annotated[ - int | None, Field(description='Total number of steps in the operation', ge=1) + int | None, Field(description="Total number of steps in the operation", ge=1) ] = None diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py index a66ad56e..f4da4f7d 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: media_buy/update_media_buy_request.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -19,19 +19,19 @@ class Packages(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bid_price: Annotated[ float | None, Field( - description='Updated bid price for auction-based pricing options (only applies when pricing_option is auction-based)', + description="Updated bid price for auction-based pricing options (only applies when pricing_option is auction-based)", ge=0.0, ), ] = None budget: Annotated[ float | None, Field( - description='Updated budget allocation for this package in the currency specified by the pricing option', + description="Updated budget allocation for this package in the currency specified by the pricing option", ge=0.0, ), ] = None @@ -41,44 +41,47 @@ class Packages(AdCPBaseModel): creative_assignments: Annotated[ list[creative_assignment.CreativeAssignment] | None, Field( - description='Full creative assignment objects with weights and placement targeting (alternative to creative_ids - provides granular control over weights and placement targeting). Uses replacement semantics like creative_ids.' + description="Full creative assignment objects with weights and placement targeting (alternative to creative_ids - provides granular control over weights and placement targeting). Uses replacement semantics like creative_ids." ), ] = None creative_ids: Annotated[ list[str] | None, - Field(description='Update creative assignments (references existing library creatives)'), + Field(description="Update creative assignments (references existing library creatives)"), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset] | None, Field( - description='Full creative objects to upload and assign to this package (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.', + description="Full creative objects to upload and assign to this package (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.", max_length=100, ), ] = None + impressions: Annotated[ + float | None, Field(description="Updated impression goal for this package", ge=0.0) + ] = None pacing: pacing_1.Pacing | None = None package_id: Annotated[str, Field(description="Publisher's ID of package to update")] paused: Annotated[ bool | None, - Field(description='Pause/resume specific package (true = paused, false = active)'), + Field(description="Pause/resume specific package (true = paused, false = active)"), ] = None targeting_overlay: targeting.TargetingOverlay | None = None class Packages1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) bid_price: Annotated[ float | None, Field( - description='Updated bid price for auction-based pricing options (only applies when pricing_option is auction-based)', + description="Updated bid price for auction-based pricing options (only applies when pricing_option is auction-based)", ge=0.0, ), ] = None budget: Annotated[ float | None, Field( - description='Updated budget allocation for this package in the currency specified by the pricing option', + description="Updated budget allocation for this package in the currency specified by the pricing option", ge=0.0, ), ] = None @@ -86,90 +89,95 @@ class Packages1(AdCPBaseModel): creative_assignments: Annotated[ list[creative_assignment.CreativeAssignment] | None, Field( - description='Full creative assignment objects with weights and placement targeting (alternative to creative_ids - provides granular control over weights and placement targeting). Uses replacement semantics like creative_ids.' + description="Full creative assignment objects with weights and placement targeting (alternative to creative_ids - provides granular control over weights and placement targeting). Uses replacement semantics like creative_ids." ), ] = None creative_ids: Annotated[ list[str] | None, - Field(description='Update creative assignments (references existing library creatives)'), + Field(description="Update creative assignments (references existing library creatives)"), ] = None creatives: Annotated[ list[creative_asset.CreativeAsset] | None, Field( - description='Full creative objects to upload and assign to this package (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.', + description="Full creative objects to upload and assign to this package (alternative to creative_ids - creatives will be added to library). Supports both static and generative creatives.", max_length=100, ), ] = None + impressions: Annotated[ + float | None, Field(description="Updated impression goal for this package", ge=0.0) + ] = None pacing: pacing_1.Pacing | None = None package_id: Annotated[str | None, Field(description="Publisher's ID of package to update")] = ( None ) paused: Annotated[ bool | None, - Field(description='Pause/resume specific package (true = paused, false = active)'), + Field(description="Pause/resume specific package (true = paused, false = active)"), ] = None targeting_overlay: targeting.TargetingOverlay | None = None class UpdateMediaBuyRequest1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[ str | None, Field(description="Buyer's reference for the media buy to update") ] = None context: context_1.ContextObject | None = None end_time: Annotated[ - AwareDatetime | None, Field(description='New end date/time in ISO 8601 format') + AwareDatetime | None, Field(description="New end date/time in ISO 8601 format") ] = None ext: ext_1.ExtensionObject | None = None media_buy_id: Annotated[str, Field(description="Publisher's ID of the media buy to update")] packages: Annotated[ - list[Packages | Packages1] | None, Field(description='Package-specific updates') + list[Packages | Packages1] | None, Field(description="Package-specific updates") ] = None paused: Annotated[ bool | None, - Field(description='Pause/resume the entire media buy (true = paused, false = active)'), + Field(description="Pause/resume the entire media buy (true = paused, false = active)"), ] = None push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( - description='Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time.' + description="Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time." ), ] = None start_time: start_timing.StartTiming | None = None -Packages2 = Packages +class Packages2(Packages): + pass -Packages3 = Packages1 +class Packages3(Packages1): + pass class UpdateMediaBuyRequest2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) buyer_ref: Annotated[str, Field(description="Buyer's reference for the media buy to update")] context: context_1.ContextObject | None = None end_time: Annotated[ - AwareDatetime | None, Field(description='New end date/time in ISO 8601 format') + AwareDatetime | None, Field(description="New end date/time in ISO 8601 format") ] = None ext: ext_1.ExtensionObject | None = None media_buy_id: Annotated[ str | None, Field(description="Publisher's ID of the media buy to update") ] = None packages: Annotated[ - list[Packages2 | Packages3] | None, Field(description='Package-specific updates') + list[Packages2 | Packages3] | None, Field(description="Package-specific updates") ] = None paused: Annotated[ bool | None, - Field(description='Pause/resume the entire media buy (true = paused, false = active)'), + Field(description="Pause/resume the entire media buy (true = paused, false = active)"), ] = None push_notification_config: Annotated[ push_notification_config_1.PushNotificationConfig | None, Field( - description='Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time.' + description="Optional webhook configuration for async update notifications. Publisher will send webhook when update completes if operation takes longer than immediate response time." ), ] = None start_time: start_timing.StartTiming | None = None @@ -179,7 +187,7 @@ class UpdateMediaBuyRequest(RootModel[UpdateMediaBuyRequest1 | UpdateMediaBuyReq root: Annotated[ UpdateMediaBuyRequest1 | UpdateMediaBuyRequest2, Field( - description='Request parameters for updating campaign and package settings', - title='Update Media Buy Request', + description="Request parameters for updating campaign and package settings", + title="Update Media Buy Request", ), ] diff --git a/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py b/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py index 35432c68..7ea1e655 100644 --- a/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py +++ b/src/adcp/types/generated_poc/media_buy/update_media_buy_response.py @@ -17,30 +17,30 @@ class UpdateMediaBuyResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], - Field(description='Array of errors explaining why the operation failed', min_length=1), + Field(description="Array of errors explaining why the operation failed", min_length=1), ] ext: ext_1.ExtensionObject | None = None class UpdateMediaBuyResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) affected_packages: Annotated[ list[package.Package] | None, - Field(description='Array of packages that were modified with complete state information'), + Field(description="Array of packages that were modified with complete state information"), ] = None buyer_ref: Annotated[str, Field(description="Buyer's reference identifier for the media buy")] context: context_1.ContextObject | None = None ext: ext_1.ExtensionObject | None = None implementation_date: Annotated[ AwareDatetime | None, - Field(description='ISO 8601 timestamp when changes take effect (null if pending approval)'), + Field(description="ISO 8601 timestamp when changes take effect (null if pending approval)"), ] = None media_buy_id: Annotated[str, Field(description="Publisher's identifier for the media buy")] @@ -49,7 +49,7 @@ class UpdateMediaBuyResponse(RootModel[UpdateMediaBuyResponse1 | UpdateMediaBuyR root: Annotated[ UpdateMediaBuyResponse1 | UpdateMediaBuyResponse2, Field( - description='Response payload for update_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - updates are either fully applied or not applied at all.', - title='Update Media Buy Response', + description="Response payload for update_media_buy task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - updates are either fully applied or not applied at all.", + title="Update Media Buy Response", ), ] diff --git a/src/adcp/types/generated_poc/pricing_options/cpc_option.py b/src/adcp/types/generated_poc/pricing_options/cpc_option.py index 9f9483b0..558dff11 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpc_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpc_option.py @@ -12,32 +12,32 @@ class CpcPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None - pricing_model: Annotated[Literal['cpc'], Field(description='Cost per click')] + pricing_model: Annotated[Literal["cpc"], Field(description="Cost per click")] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpc_usd_fixed')" ), ] - rate: Annotated[float, Field(description='Fixed CPC rate (cost per click)', ge=0.0)] + rate: Annotated[float, Field(description="Fixed CPC rate (cost per click)", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/cpcv_option.py b/src/adcp/types/generated_poc/pricing_options/cpcv_option.py index abe88f5a..6765ba50 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpcv_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpcv_option.py @@ -12,29 +12,29 @@ class CpcvPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None pricing_model: Annotated[ - Literal['cpcv'], Field(description='Cost per completed view (100% completion)') + Literal["cpcv"], Field(description="Cost per completed view (100% completion)") ] pricing_option_id: Annotated[ str, @@ -42,4 +42,4 @@ class CpcvPricingOption(AdCPBaseModel): description="Unique identifier for this pricing option within the product (e.g., 'cpcv_usd_guaranteed')" ), ] - rate: Annotated[float, Field(description='Fixed CPCV rate (cost per 100% completion)', ge=0.0)] + rate: Annotated[float, Field(description="Fixed CPCV rate (cost per 100% completion)", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/cpm_auction_option.py b/src/adcp/types/generated_poc/pricing_options/cpm_auction_option.py index e6855143..e8de619b 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpm_auction_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpm_auction_option.py @@ -14,42 +14,42 @@ class PriceGuidance(AdCPBaseModel): floor: Annotated[ float, Field( - description='Minimum bid price - publisher will reject bids under this value', ge=0.0 + description="Minimum bid price - publisher will reject bids under this value", ge=0.0 ), ] - p25: Annotated[float | None, Field(description='25th percentile winning price', ge=0.0)] = None - p50: Annotated[float | None, Field(description='Median winning price', ge=0.0)] = None - p75: Annotated[float | None, Field(description='75th percentile winning price', ge=0.0)] = None - p90: Annotated[float | None, Field(description='90th percentile winning price', ge=0.0)] = None + p25: Annotated[float | None, Field(description="25th percentile winning price", ge=0.0)] = None + p50: Annotated[float | None, Field(description="Median winning price", ge=0.0)] = None + p75: Annotated[float | None, Field(description="75th percentile winning price", ge=0.0)] = None + p90: Annotated[float | None, Field(description="90th percentile winning price", ge=0.0)] = None class CpmAuctionPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[False], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None price_guidance: Annotated[ - PriceGuidance, Field(description='Pricing guidance for auction-based CPM bidding') + PriceGuidance, Field(description="Pricing guidance for auction-based CPM bidding") ] - pricing_model: Annotated[Literal['cpm'], Field(description='Cost per 1,000 impressions')] + pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] pricing_option_id: Annotated[ str, Field( diff --git a/src/adcp/types/generated_poc/pricing_options/cpm_fixed_option.py b/src/adcp/types/generated_poc/pricing_options/cpm_fixed_option.py index fa0b81c3..db5a3e1e 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpm_fixed_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpm_fixed_option.py @@ -12,32 +12,32 @@ class CpmFixedRatePricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None - pricing_model: Annotated[Literal['cpm'], Field(description='Cost per 1,000 impressions')] + pricing_model: Annotated[Literal["cpm"], Field(description="Cost per 1,000 impressions")] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpm_usd_guaranteed')" ), ] - rate: Annotated[float, Field(description='Fixed CPM rate (cost per 1,000 impressions)', ge=0.0)] + rate: Annotated[float, Field(description="Fixed CPM rate (cost per 1,000 impressions)", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/cpp_option.py b/src/adcp/types/generated_poc/pricing_options/cpp_option.py index 8cc2bffc..807cd3cc 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpp_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpp_option.py @@ -12,53 +12,53 @@ class Parameters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) demographic: Annotated[ str, Field( - description='Target demographic in Nielsen format: P/M/W/A/C + age range. Examples: P18-49 (Persons 18-49), M25-54 (Men 25-54), W35+ (Women 35+), A18-34 (Adults 18-34), C2-11 (Children 2-11)', - pattern='^[PMWAC][0-9]{2}(-[0-9]{2}|\\+)$', + description="Target demographic in Nielsen format: P/M/W/A/C + age range. Examples: P18-49 (Persons 18-49), M25-54 (Men 25-54), W35+ (Women 35+), A18-34 (Adults 18-34), C2-11 (Children 2-11)", + pattern="^[PMWAC][0-9]{2}(-[0-9]{2}|\\+)$", ), ] min_points: Annotated[ float | None, - Field(description='Minimum GRPs/TRPs required for this pricing option', ge=0.0), + Field(description="Minimum GRPs/TRPs required for this pricing option", ge=0.0), ] = None class CppPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None parameters: Annotated[ Parameters, - Field(description='CPP-specific parameters for demographic targeting and GRP requirements'), + Field(description="CPP-specific parameters for demographic targeting and GRP requirements"), ] - pricing_model: Annotated[Literal['cpp'], Field(description='Cost per Gross Rating Point')] + pricing_model: Annotated[Literal["cpp"], Field(description="Cost per Gross Rating Point")] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpp_usd_p18-49')" ), ] - rate: Annotated[float, Field(description='Fixed CPP rate (cost per rating point)', ge=0.0)] + rate: Annotated[float, Field(description="Fixed CPP rate (cost per rating point)", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/cpv_option.py b/src/adcp/types/generated_poc/pricing_options/cpv_option.py index 24a72d73..793c22c4 100644 --- a/src/adcp/types/generated_poc/pricing_options/cpv_option.py +++ b/src/adcp/types/generated_poc/pricing_options/cpv_option.py @@ -14,7 +14,7 @@ class ViewThreshold(RootModel[float]): root: Annotated[ float, Field( - description='Percentage completion threshold for CPV pricing (0.0 to 1.0, e.g., 0.5 = 50% completion)', + description="Percentage completion threshold for CPV pricing (0.0 to 1.0, e.g., 0.5 = 50% completion)", ge=0.0, le=1.0, ), @@ -23,7 +23,7 @@ class ViewThreshold(RootModel[float]): class ViewThreshold1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) duration_seconds: Annotated[ int, @@ -36,42 +36,42 @@ class ViewThreshold1(AdCPBaseModel): class Parameters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) view_threshold: ViewThreshold | ViewThreshold1 class CpvPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None parameters: Annotated[ - Parameters, Field(description='CPV-specific parameters defining the view threshold') + Parameters, Field(description="CPV-specific parameters defining the view threshold") ] - pricing_model: Annotated[Literal['cpv'], Field(description='Cost per view at threshold')] + pricing_model: Annotated[Literal["cpv"], Field(description="Cost per view at threshold")] pricing_option_id: Annotated[ str, Field( description="Unique identifier for this pricing option within the product (e.g., 'cpv_usd_50pct')" ), ] - rate: Annotated[float, Field(description='Fixed CPV rate (cost per view)', ge=0.0)] + rate: Annotated[float, Field(description="Fixed CPV rate (cost per view)", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py b/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py index d57b7e78..762e7bc3 100644 --- a/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py +++ b/src/adcp/types/generated_poc/pricing_options/flat_rate_option.py @@ -12,7 +12,7 @@ class Parameters(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) daypart: Annotated[ str | None, @@ -22,28 +22,28 @@ class Parameters(AdCPBaseModel): ] = None duration_hours: Annotated[ float | None, - Field(description='Duration in hours for time-based flat rate pricing (DOOH)', ge=0.0), + Field(description="Duration in hours for time-based flat rate pricing (DOOH)", ge=0.0), ] = None estimated_impressions: Annotated[ int | None, Field( - description='Estimated impressions for this flat rate option (informational, commonly used with SOV or time-based DOOH)', + description="Estimated impressions for this flat rate option (informational, commonly used with SOV or time-based DOOH)", ge=0, ), ] = None loop_duration_seconds: Annotated[ - int | None, Field(description='Duration of ad loop rotation in seconds (DOOH)', ge=1) + int | None, Field(description="Duration of ad loop rotation in seconds (DOOH)", ge=1) ] = None min_plays_per_hour: Annotated[ int | None, Field( - description='Minimum number of times ad plays per hour (DOOH frequency guarantee)', ge=0 + description="Minimum number of times ad plays per hour (DOOH frequency guarantee)", ge=0 ), ] = None sov_percentage: Annotated[ float | None, Field( - description='Guaranteed share of voice as percentage (DOOH, 0-100)', ge=0.0, le=100.0 + description="Guaranteed share of voice as percentage (DOOH, 0-100)", ge=0.0, le=100.0 ), ] = None venue_package: Annotated[ @@ -56,33 +56,33 @@ class Parameters(AdCPBaseModel): class FlatRatePricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None parameters: Annotated[ Parameters | None, - Field(description='Flat rate parameters for DOOH and time-based campaigns'), + Field(description="Flat rate parameters for DOOH and time-based campaigns"), ] = None pricing_model: Annotated[ - Literal['flat_rate'], Field(description='Fixed cost regardless of delivery volume') + Literal["flat_rate"], Field(description="Fixed cost regardless of delivery volume") ] pricing_option_id: Annotated[ str, @@ -90,4 +90,4 @@ class FlatRatePricingOption(AdCPBaseModel): description="Unique identifier for this pricing option within the product (e.g., 'flat_rate_usd_24h_takeover')" ), ] - rate: Annotated[float, Field(description='Flat rate cost', ge=0.0)] + rate: Annotated[float, Field(description="Flat rate cost", ge=0.0)] diff --git a/src/adcp/types/generated_poc/pricing_options/vcpm_auction_option.py b/src/adcp/types/generated_poc/pricing_options/vcpm_auction_option.py index 7790e5b9..6e017f1f 100644 --- a/src/adcp/types/generated_poc/pricing_options/vcpm_auction_option.py +++ b/src/adcp/types/generated_poc/pricing_options/vcpm_auction_option.py @@ -11,47 +11,47 @@ class PriceGuidance(AdCPBaseModel): - floor: Annotated[float, Field(description='Minimum acceptable bid price', ge=0.0)] + floor: Annotated[float, Field(description="Minimum acceptable bid price", ge=0.0)] p25: Annotated[ - float | None, Field(description='25th percentile of recent winning bids', ge=0.0) + float | None, Field(description="25th percentile of recent winning bids", ge=0.0) ] = None - p50: Annotated[float | None, Field(description='Median of recent winning bids', ge=0.0)] = None + p50: Annotated[float | None, Field(description="Median of recent winning bids", ge=0.0)] = None p75: Annotated[ - float | None, Field(description='75th percentile of recent winning bids', ge=0.0) + float | None, Field(description="75th percentile of recent winning bids", ge=0.0) ] = None p90: Annotated[ - float | None, Field(description='90th percentile of recent winning bids', ge=0.0) + float | None, Field(description="90th percentile of recent winning bids", ge=0.0) ] = None class VcpmAuctionPricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[False], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None price_guidance: Annotated[ - PriceGuidance, Field(description='Statistical guidance for auction pricing') + PriceGuidance, Field(description="Statistical guidance for auction pricing") ] pricing_model: Annotated[ - Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)') + Literal["vcpm"], Field(description="Cost per 1,000 viewable impressions (MRC standard)") ] pricing_option_id: Annotated[ str, diff --git a/src/adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py b/src/adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py index bf6fc44c..acbaf110 100644 --- a/src/adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py +++ b/src/adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py @@ -12,29 +12,29 @@ class VcpmFixedRatePricingOption(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) currency: Annotated[ str, Field( - description='ISO 4217 currency code', - examples=['USD', 'EUR', 'GBP', 'JPY'], - pattern='^[A-Z]{3}$', + description="ISO 4217 currency code", + examples=["USD", "EUR", "GBP", "JPY"], + pattern="^[A-Z]{3}$", ), ] is_fixed: Annotated[ Literal[True], - Field(description='Whether this is a fixed rate (true) or auction-based (false)'), + Field(description="Whether this is a fixed rate (true) or auction-based (false)"), ] min_spend_per_package: Annotated[ float | None, Field( - description='Minimum spend requirement per package using this pricing option, in the specified currency', + description="Minimum spend requirement per package using this pricing option, in the specified currency", ge=0.0, ), ] = None pricing_model: Annotated[ - Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)') + Literal["vcpm"], Field(description="Cost per 1,000 viewable impressions (MRC standard)") ] pricing_option_id: Annotated[ str, @@ -43,5 +43,5 @@ class VcpmFixedRatePricingOption(AdCPBaseModel): ), ] rate: Annotated[ - float, Field(description='Fixed vCPM rate (cost per 1,000 viewable impressions)', ge=0.0) + float, Field(description="Fixed vCPM rate (cost per 1,000 viewable impressions)", ge=0.0) ] diff --git a/src/adcp/types/generated_poc/property/__init__.py b/src/adcp/types/generated_poc/property/__init__.py new file mode 100644 index 00000000..5334de51 --- /dev/null +++ b/src/adcp/types/generated_poc/property/__init__.py @@ -0,0 +1,3 @@ +# generated by datamodel-codegen: +# filename: .schema_temp +# timestamp: 2026-01-14T17:08:13+00:00 diff --git a/src/adcp/types/generated_poc/property/base_property_source.py b/src/adcp/types/generated_poc/property/base_property_source.py new file mode 100644 index 00000000..aadc0111 --- /dev/null +++ b/src/adcp/types/generated_poc/property/base_property_source.py @@ -0,0 +1,86 @@ +# generated by datamodel-codegen: +# filename: property/base_property_source.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated, Literal + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field, RootModel + +from ..core import identifier, property_id, property_tag + + +class BasePropertySource1(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + publisher_domain: Annotated[ + str, + Field( + description="Domain where publisher's adagents.json is hosted (e.g., 'raptive.com')", + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", + ), + ] + selection_type: Annotated[ + Literal["publisher_tags"], + Field(description="Discriminator indicating selection by property tags within a publisher"), + ] + tags: Annotated[ + list[property_tag.PropertyTag], + Field( + description="Property tags from the publisher's adagents.json. Selects all properties with these tags.", + min_length=1, + ), + ] + + +class BasePropertySource2(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + property_ids: Annotated[ + list[property_id.PropertyId], + Field(description="Specific property IDs from the publisher's adagents.json", min_length=1), + ] + publisher_domain: Annotated[ + str, + Field( + description="Domain where publisher's adagents.json is hosted (e.g., 'raptive.com')", + pattern="^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$", + ), + ] + selection_type: Annotated[ + Literal["publisher_ids"], + Field( + description="Discriminator indicating selection by specific property IDs within a publisher" + ), + ] + + +class BasePropertySource3(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + identifiers: Annotated[ + list[identifier.Identifier], + Field(description="Direct property identifiers (domains, app IDs, etc.)", min_length=1), + ] + selection_type: Annotated[ + Literal["identifiers"], + Field(description="Discriminator indicating selection by direct identifiers"), + ] + + +class BasePropertySource( + RootModel[BasePropertySource1 | BasePropertySource2 | BasePropertySource3] +): + root: Annotated[ + BasePropertySource1 | BasePropertySource2 | BasePropertySource3, + Field( + description="A source of properties for a property list. Supports three selection patterns: publisher with tags, publisher with property IDs, or direct identifiers.", + discriminator="selection_type", + title="Base Property Source", + ), + ] diff --git a/src/adcp/types/generated_poc/property/create_property_list_request.py b/src/adcp/types/generated_poc/property/create_property_list_request.py new file mode 100644 index 00000000..820e53d7 --- /dev/null +++ b/src/adcp/types/generated_poc/property/create_property_list_request.py @@ -0,0 +1,43 @@ +# generated by datamodel-codegen: +# filename: property/create_property_list_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import brand_manifest as brand_manifest_1 +from ..core import context as context_1 +from ..core import ext as ext_1 +from . import base_property_source, property_list_filters + + +class CreatePropertyListRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + base_properties: Annotated[ + list[base_property_source.BasePropertySource] | None, + Field( + description="Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database." + ), + ] = None + brand_manifest: Annotated[ + brand_manifest_1.BrandManifest | None, + Field( + description="Brand identity and requirements. When provided, the agent automatically applies appropriate rules based on brand characteristics (industry, target_audience, etc.)." + ), + ] = None + context: context_1.ContextObject | None = None + description: Annotated[str | None, Field(description="Description of the list's purpose")] = ( + None + ) + ext: ext_1.ExtensionObject | None = None + filters: Annotated[ + property_list_filters.PropertyListFilters | None, + Field(description="Dynamic filters to apply when resolving the list"), + ] = None + name: Annotated[str, Field(description="Human-readable name for the list")] diff --git a/src/adcp/types/generated_poc/property/create_property_list_response.py b/src/adcp/types/generated_poc/property/create_property_list_response.py new file mode 100644 index 00000000..c8927596 --- /dev/null +++ b/src/adcp/types/generated_poc/property/create_property_list_response.py @@ -0,0 +1,27 @@ +# generated by datamodel-codegen: +# filename: property/create_property_list_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 +from . import property_list + + +class CreatePropertyListResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + auth_token: Annotated[ + str, + Field( + description="Token that can be shared with sellers to authorize fetching this list. Store this - it is only returned at creation time." + ), + ] + ext: ext_1.ExtensionObject | None = None + list: Annotated[property_list.PropertyList, Field(description="The created property list")] diff --git a/src/adcp/types/generated_poc/property/delete_property_list_request.py b/src/adcp/types/generated_poc/property/delete_property_list_request.py new file mode 100644 index 00000000..4729a744 --- /dev/null +++ b/src/adcp/types/generated_poc/property/delete_property_list_request.py @@ -0,0 +1,22 @@ +# generated by datamodel-codegen: +# filename: property/delete_property_list_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import context as context_1 +from ..core import ext as ext_1 + + +class DeletePropertyListRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + context: context_1.ContextObject | None = None + ext: ext_1.ExtensionObject | None = None + list_id: Annotated[str, Field(description="ID of the property list to delete")] diff --git a/src/adcp/types/generated_poc/property/delete_property_list_response.py b/src/adcp/types/generated_poc/property/delete_property_list_response.py new file mode 100644 index 00000000..3def64b6 --- /dev/null +++ b/src/adcp/types/generated_poc/property/delete_property_list_response.py @@ -0,0 +1,21 @@ +# generated by datamodel-codegen: +# filename: property/delete_property_list_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 + + +class DeletePropertyListResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + deleted: Annotated[bool, Field(description="Whether the list was successfully deleted")] + ext: ext_1.ExtensionObject | None = None + list_id: Annotated[str, Field(description="ID of the deleted list")] diff --git a/src/adcp/types/generated_poc/property/feature_requirement.py b/src/adcp/types/generated_poc/property/feature_requirement.py new file mode 100644 index 00000000..1ea5e6f7 --- /dev/null +++ b/src/adcp/types/generated_poc/property/feature_requirement.py @@ -0,0 +1,42 @@ +# generated by datamodel-codegen: +# filename: property/feature_requirement.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Annotated, Any + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + + +class IfNotCovered(Enum): + exclude = "exclude" + include = "include" + + +class FeatureRequirement(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + allowed_values: Annotated[ + list[Any] | None, + Field(description="Values that pass the requirement (for binary/categorical features)"), + ] = None + feature_id: Annotated[ + str, Field(description="Feature to evaluate (discovered via list_property_features)") + ] + if_not_covered: Annotated[ + IfNotCovered | None, + Field( + description="How to handle properties where this feature is not covered. 'exclude' (default): property is removed from the list. 'include': property passes this requirement (fail-open)." + ), + ] = IfNotCovered.exclude + max_value: Annotated[ + float | None, Field(description="Maximum numeric value allowed (for quantitative features)") + ] = None + min_value: Annotated[ + float | None, + Field(description="Minimum numeric value required (for quantitative features)"), + ] = None diff --git a/src/adcp/types/generated_poc/property/get_property_list_request.py b/src/adcp/types/generated_poc/property/get_property_list_request.py new file mode 100644 index 00000000..656c2808 --- /dev/null +++ b/src/adcp/types/generated_poc/property/get_property_list_request.py @@ -0,0 +1,34 @@ +# generated by datamodel-codegen: +# filename: property/get_property_list_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import context as context_1 +from ..core import ext as ext_1 + + +class GetPropertyListRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + context: context_1.ContextObject | None = None + cursor: Annotated[str | None, Field(description="Pagination cursor for large result sets")] = ( + None + ) + ext: ext_1.ExtensionObject | None = None + list_id: Annotated[str, Field(description="ID of the property list to retrieve")] + max_results: Annotated[ + int | None, Field(description="Maximum identifiers to return (for large lists)", ge=1) + ] = None + resolve: Annotated[ + bool | None, + Field( + description="Whether to apply filters and return resolved identifiers (default: true)" + ), + ] = True diff --git a/src/adcp/types/generated_poc/property/get_property_list_response.py b/src/adcp/types/generated_poc/property/get_property_list_response.py new file mode 100644 index 00000000..9b5df6db --- /dev/null +++ b/src/adcp/types/generated_poc/property/get_property_list_response.py @@ -0,0 +1,61 @@ +# generated by datamodel-codegen: +# filename: property/get_property_list_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AwareDatetime, ConfigDict, Field + +from ..core import ext as ext_1 +from ..core import identifier +from . import property_list + + +class Pagination(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + cursor: Annotated[str | None, Field(description="Cursor for next page")] = None + has_more: Annotated[bool | None, Field(description="Whether more results are available")] = None + + +class GetPropertyListResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + cache_valid_until: Annotated[ + AwareDatetime | None, + Field( + description="Cache expiration timestamp. Re-fetch the list after this time to get updated identifiers." + ), + ] = None + coverage_gaps: Annotated[ + dict[str, list[identifier.Identifier]] | None, + Field( + description="Properties included in the list despite missing feature data. Only present when a feature_requirement has if_not_covered='include'. Maps feature_id to list of identifiers not covered for that feature." + ), + ] = None + ext: ext_1.ExtensionObject | None = None + identifiers: Annotated[ + list[identifier.Identifier] | None, + Field( + description="Resolved identifiers that passed filters (if resolve=true). Cache these locally for real-time use." + ), + ] = None + list: Annotated[ + property_list.PropertyList, + Field(description="The property list metadata (always returned)"), + ] + pagination: Annotated[Pagination | None, Field(description="Pagination information")] = None + resolved_at: Annotated[ + AwareDatetime | None, Field(description="When the list was resolved") + ] = None + returned_count: Annotated[ + int | None, Field(description="Number of identifiers returned in this response") + ] = None + total_count: Annotated[ + int | None, Field(description="Total number of identifiers in resolved list") + ] = None diff --git a/src/adcp/types/generated_poc/property/list_property_features_request.py b/src/adcp/types/generated_poc/property/list_property_features_request.py new file mode 100644 index 00000000..94665a09 --- /dev/null +++ b/src/adcp/types/generated_poc/property/list_property_features_request.py @@ -0,0 +1,25 @@ +# generated by datamodel-codegen: +# filename: property/list_property_features_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 + + +class ListPropertyFeaturesRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + countries: Annotated[ + list[str] | None, Field(description="Filter to features available in these countries") + ] = None + ext: ext_1.ExtensionObject | None = None + property_types: Annotated[ + list[str] | None, Field(description="Filter to features available for these property types") + ] = None diff --git a/src/adcp/types/generated_poc/property/list_property_features_response.py b/src/adcp/types/generated_poc/property/list_property_features_response.py new file mode 100644 index 00000000..b099f4aa --- /dev/null +++ b/src/adcp/types/generated_poc/property/list_property_features_response.py @@ -0,0 +1,24 @@ +# generated by datamodel-codegen: +# filename: property/list_property_features_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 +from . import property_feature_definition + + +class ListPropertyFeaturesResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + ext: ext_1.ExtensionObject | None = None + features: Annotated[ + list[property_feature_definition.PropertyFeatureDefinition], + Field(description="Features this agent can evaluate"), + ] diff --git a/src/adcp/types/generated_poc/property/list_property_lists_request.py b/src/adcp/types/generated_poc/property/list_property_lists_request.py new file mode 100644 index 00000000..fabe6af2 --- /dev/null +++ b/src/adcp/types/generated_poc/property/list_property_lists_request.py @@ -0,0 +1,29 @@ +# generated by datamodel-codegen: +# filename: property/list_property_lists_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import context as context_1 +from ..core import ext as ext_1 + + +class ListPropertyListsRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + context: context_1.ContextObject | None = None + cursor: Annotated[str | None, Field(description="Pagination cursor")] = None + ext: ext_1.ExtensionObject | None = None + max_results: Annotated[int | None, Field(description="Maximum lists to return", ge=1)] = 100 + name_contains: Annotated[ + str | None, Field(description="Filter to lists whose name contains this string") + ] = None + principal: Annotated[ + str | None, Field(description="Filter to lists owned by this principal") + ] = None diff --git a/src/adcp/types/generated_poc/property/list_property_lists_response.py b/src/adcp/types/generated_poc/property/list_property_lists_response.py new file mode 100644 index 00000000..ba9c392c --- /dev/null +++ b/src/adcp/types/generated_poc/property/list_property_lists_response.py @@ -0,0 +1,39 @@ +# generated by datamodel-codegen: +# filename: property/list_property_lists_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 +from . import property_list + + +class Pagination(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + cursor: Annotated[str | None, Field(description="Cursor for next page")] = None + has_more: Annotated[bool | None, Field(description="Whether more results are available")] = None + + +class ListPropertyListsResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + ext: ext_1.ExtensionObject | None = None + lists: Annotated[ + list[property_list.PropertyList], + Field(description="Array of property lists (metadata only, not resolved properties)"), + ] + pagination: Annotated[Pagination | None, Field(description="Pagination information")] = None + returned_count: Annotated[ + int | None, Field(description="Number of lists returned in this response") + ] = None + total_count: Annotated[ + int | None, Field(description="Total number of lists matching criteria") + ] = None diff --git a/src/adcp/types/generated_poc/property/property_error.py b/src/adcp/types/generated_poc/property/property_error.py new file mode 100644 index 00000000..aeb92645 --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_error.py @@ -0,0 +1,33 @@ +# generated by datamodel-codegen: +# filename: property/property_error.json +# timestamp: 2026-01-14T17:08:13+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 + +from ..core import property as property_1 + + +class Code(Enum): + PROPERTY_NOT_FOUND = "PROPERTY_NOT_FOUND" + PROPERTY_NOT_MONITORED = "PROPERTY_NOT_MONITORED" + LIST_NOT_FOUND = "LIST_NOT_FOUND" + LIST_ACCESS_DENIED = "LIST_ACCESS_DENIED" + METHODOLOGY_NOT_SUPPORTED = "METHODOLOGY_NOT_SUPPORTED" + JURISDICTION_NOT_SUPPORTED = "JURISDICTION_NOT_SUPPORTED" + + +class PropertyError(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + code: Annotated[Code, Field(description="Error code")] + message: Annotated[str, Field(description="Human-readable error message")] + property: Annotated[ + property_1.Property | None, Field(description="The property that caused the error") + ] = None diff --git a/src/adcp/types/generated_poc/property/property_feature.py b/src/adcp/types/generated_poc/property/property_feature.py new file mode 100644 index 00000000..6ebca903 --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_feature.py @@ -0,0 +1,22 @@ +# generated by datamodel-codegen: +# filename: property/property_feature.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + + +class PropertyFeature(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + feature_id: Annotated[str, Field(description="Identifier for the feature being assessed")] + source: Annotated[ + str | None, + Field(description="Source of the feature data (e.g., app_store_privacy_label, tcf_string)"), + ] = None + value: Annotated[str, Field(description="The feature value")] diff --git a/src/adcp/types/generated_poc/property/property_feature_definition.py b/src/adcp/types/generated_poc/property/property_feature_definition.py new file mode 100644 index 00000000..88cc619a --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_feature_definition.py @@ -0,0 +1,80 @@ +# generated by datamodel-codegen: +# filename: property/property_feature_definition.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from enum import Enum +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, ConfigDict, Field + +from ..core import ext as ext_1 + + +class Coverage(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + countries: Annotated[ + list[str] | None, Field(description="Countries where this feature is available") + ] = None + property_types: Annotated[ + list[str] | None, Field(description="Property types this feature applies to") + ] = None + + +class Range(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + max: Annotated[float, Field(description="Maximum value")] + min: Annotated[float, Field(description="Minimum value")] + + +class Type(Enum): + binary = "binary" + quantitative = "quantitative" + categorical = "categorical" + + +class PropertyFeatureDefinition(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + allowed_values: Annotated[ + list[str] | None, Field(description="For categorical features, the set of valid values") + ] = None + coverage: Annotated[ + Coverage | None, Field(description="What this feature covers (empty arrays = all)") + ] = None + description: Annotated[ + str | None, Field(description="Description of what this feature measures or represents") + ] = None + ext: ext_1.ExtensionObject | None = None + feature_id: Annotated[ + str, + Field( + description="Unique identifier for this feature (e.g., 'consent_quality', 'carbon_score', 'coppa_certified')" + ), + ] + methodology_url: Annotated[ + AnyUrl, + Field( + description="URL to documentation explaining how this feature is calculated/measured" + ), + ] + methodology_version: Annotated[ + str | None, Field(description="Version identifier for the methodology (for audit trails)") + ] = None + name: Annotated[str, Field(description="Human-readable name for the feature")] + range: Annotated[ + Range | None, Field(description="For quantitative features, the valid range of values") + ] = None + type: Annotated[ + Type, + Field( + description="The type of values this feature produces: binary (true/false), quantitative (numeric range), categorical (enumerated values)" + ), + ] diff --git a/src/adcp/types/generated_poc/property/property_list.py b/src/adcp/types/generated_poc/property/property_list.py new file mode 100644 index 00000000..e3d1e05f --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_list.py @@ -0,0 +1,62 @@ +# generated by datamodel-codegen: +# filename: property/property_list.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, AwareDatetime, ConfigDict, Field + +from ..core import brand_manifest as brand_manifest_1 +from . import base_property_source, property_list_filters + + +class PropertyList(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + base_properties: Annotated[ + list[base_property_source.BasePropertySource] | None, + Field( + description="Array of property sources to evaluate. Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers). If omitted, queries the agent's entire property database." + ), + ] = None + brand_manifest: Annotated[ + brand_manifest_1.BrandManifest | None, + Field(description="Brand identity used to automatically apply appropriate rules"), + ] = None + cache_duration_hours: Annotated[ + int | None, + Field( + description="Recommended cache duration for resolved list. Consumers should re-fetch after this period.", + ge=1, + ), + ] = 24 + created_at: Annotated[AwareDatetime | None, Field(description="When the list was created")] = ( + None + ) + description: Annotated[str | None, Field(description="Description of the list's purpose")] = ( + None + ) + filters: Annotated[ + property_list_filters.PropertyListFilters | None, + Field(description="Dynamic filters applied when resolving the list"), + ] = None + list_id: Annotated[str, Field(description="Unique identifier for this property list")] + name: Annotated[str, Field(description="Human-readable name for the list")] + principal: Annotated[ + str | None, Field(description="Principal identity that owns this list") + ] = None + property_count: Annotated[ + int | None, + Field(description="Number of properties in the resolved list (at time of last resolution)"), + ] = None + updated_at: Annotated[ + AwareDatetime | None, Field(description="When the list was last modified") + ] = None + webhook_url: Annotated[ + AnyUrl | None, + Field(description="URL to receive notifications when the resolved list changes"), + ] = None diff --git a/src/adcp/types/generated_poc/property/property_list_changed_webhook.py b/src/adcp/types/generated_poc/property/property_list_changed_webhook.py new file mode 100644 index 00000000..baec0a5d --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_list_changed_webhook.py @@ -0,0 +1,51 @@ +# generated by datamodel-codegen: +# filename: property/property_list_changed_webhook.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated, Literal + +from adcp.types.base import AdCPBaseModel +from pydantic import AwareDatetime, ConfigDict, Field + +from ..core import ext as ext_1 + + +class ChangeSummary(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + properties_added: Annotated[ + int | None, Field(description="Number of properties added since last resolution") + ] = None + properties_removed: Annotated[ + int | None, Field(description="Number of properties removed since last resolution") + ] = None + total_properties: Annotated[ + int | None, Field(description="Total properties in the resolved list") + ] = None + + +class PropertyListChangedWebhook(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + cache_valid_until: Annotated[ + AwareDatetime | None, + Field(description="When the consumer should refresh from the governance agent"), + ] = None + change_summary: Annotated[ + ChangeSummary | None, Field(description="Summary of changes to the resolved list") + ] = None + event: Annotated[Literal["property_list_changed"], Field(description="The event type")] + ext: ext_1.ExtensionObject | None = None + list_id: Annotated[str, Field(description="ID of the property list that changed")] + list_name: Annotated[str | None, Field(description="Name of the property list")] = None + resolved_at: Annotated[AwareDatetime, Field(description="When the list was re-resolved")] + signature: Annotated[ + str, + Field( + description="Cryptographic signature of the webhook payload, signed with the agent's private key. Recipients MUST verify this signature." + ), + ] diff --git a/src/adcp/types/generated_poc/property/property_list_filters.py b/src/adcp/types/generated_poc/property/property_list_filters.py new file mode 100644 index 00000000..4b5dd305 --- /dev/null +++ b/src/adcp/types/generated_poc/property/property_list_filters.py @@ -0,0 +1,47 @@ +# generated by datamodel-codegen: +# filename: property/property_list_filters.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field, RootModel + +from ..core import identifier +from ..enums import channels, property_type +from . import feature_requirement + + +class CountriesAllItem(RootModel[str]): + root: Annotated[str, Field(pattern="^[A-Z]{2}$")] + + +class PropertyListFilters(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + channels_any: Annotated[ + list[channels.AdvertisingChannels], + Field(description="Property must support ANY of the listed channels. Required."), + ] + countries_all: Annotated[ + list[CountriesAllItem], + Field( + description="Property must have feature data for ALL listed countries (ISO codes). Required." + ), + ] + exclude_identifiers: Annotated[ + list[identifier.Identifier] | None, + Field(description="Identifiers to always exclude from results"), + ] = None + feature_requirements: Annotated[ + list[feature_requirement.FeatureRequirement] | None, + Field( + description="Feature-based requirements. Property must pass ALL requirements (AND logic)." + ), + ] = None + property_types: Annotated[ + list[property_type.PropertyType] | None, Field(description="Filter to these property types") + ] = None diff --git a/src/adcp/types/generated_poc/property/update_property_list_request.py b/src/adcp/types/generated_poc/property/update_property_list_request.py new file mode 100644 index 00000000..a5028ba2 --- /dev/null +++ b/src/adcp/types/generated_poc/property/update_property_list_request.py @@ -0,0 +1,46 @@ +# generated by datamodel-codegen: +# filename: property/update_property_list_request.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import AnyUrl, ConfigDict, Field + +from ..core import brand_manifest as brand_manifest_1 +from ..core import context as context_1 +from ..core import ext as ext_1 +from . import base_property_source, property_list_filters + + +class UpdatePropertyListRequest(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + base_properties: Annotated[ + list[base_property_source.BasePropertySource] | None, + Field( + description="Complete replacement for the base properties list (not a patch). Each entry is a discriminated union: publisher_tags (publisher_domain + tags), publisher_ids (publisher_domain + property_ids), or identifiers (direct identifiers)." + ), + ] = None + brand_manifest: Annotated[ + brand_manifest_1.BrandManifest | None, + Field(description="Update brand identity and requirements"), + ] = None + context: context_1.ContextObject | None = None + description: Annotated[str | None, Field(description="New description")] = None + ext: ext_1.ExtensionObject | None = None + filters: Annotated[ + property_list_filters.PropertyListFilters | None, + Field(description="Complete replacement for the filters (not a patch)"), + ] = None + list_id: Annotated[str, Field(description="ID of the property list to update")] + name: Annotated[str | None, Field(description="New name for the list")] = None + webhook_url: Annotated[ + AnyUrl | None, + Field( + description="Update the webhook URL for list change notifications (set to empty string to remove)" + ), + ] = None diff --git a/src/adcp/types/generated_poc/property/update_property_list_response.py b/src/adcp/types/generated_poc/property/update_property_list_response.py new file mode 100644 index 00000000..e8bf8875 --- /dev/null +++ b/src/adcp/types/generated_poc/property/update_property_list_response.py @@ -0,0 +1,21 @@ +# generated by datamodel-codegen: +# filename: property/update_property_list_response.json +# timestamp: 2026-01-14T17:08:13+00:00 + +from __future__ import annotations + +from typing import Annotated + +from adcp.types.base import AdCPBaseModel +from pydantic import ConfigDict, Field + +from ..core import ext as ext_1 +from . import property_list + + +class UpdatePropertyListResponse(AdCPBaseModel): + model_config = ConfigDict( + extra="forbid", + ) + ext: ext_1.ExtensionObject | None = None + list: Annotated[property_list.PropertyList, Field(description="The updated property list")] diff --git a/src/adcp/types/generated_poc/protocols/adcp_extension.py b/src/adcp/types/generated_poc/protocols/adcp_extension.py index e02a3471..f410049d 100644 --- a/src/adcp/types/generated_poc/protocols/adcp_extension.py +++ b/src/adcp/types/generated_poc/protocols/adcp_extension.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: protocols/adcp_extension.json -# timestamp: 2026-01-08T19:25:24+00:00 +# timestamp: 2026-01-14T17:08:13+00:00 from __future__ import annotations @@ -8,30 +8,46 @@ from typing import Annotated from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field +from pydantic import ConfigDict, Field, RootModel + + +class ExtensionsSupportedItem(RootModel[str]): + root: Annotated[ + str, + Field( + description="Extension namespace (e.g., 'sustainability'). Must be lowercase alphanumeric with underscores.", + pattern="^[a-z][a-z0-9_]*$", + ), + ] class ProtocolsSupportedEnum(Enum): - media_buy = 'media_buy' - creative = 'creative' - signals = 'signals' + media_buy = "media_buy" + creative = "creative" + signals = "signals" -class AdcpAgentCardExtension(AdCPBaseModel): +class AdcpAgentCardExtensionParams(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) adcp_version: Annotated[ str, Field( - description="Semantic version of the AdCP specification this agent implements (e.g., '2.4.0')", - pattern='^\\d+\\.\\d+\\.\\d+$', + description="Semantic version of the AdCP specification this agent implements (e.g., '2.5.0'). Extension schemas are versioned along with the AdCP spec.", + pattern="^\\d+\\.\\d+\\.\\d+$", ), ] + extensions_supported: Annotated[ + list[ExtensionsSupportedItem] | None, + Field( + description="Typed extensions this agent supports. Each extension has a formal schema in /schemas/extensions/. Extension version is determined by adcp_version." + ), + ] = None protocols_supported: Annotated[ list[ProtocolsSupportedEnum], Field( - description='AdCP protocol domains supported by this agent. At least one must be specified.', + description="AdCP protocol domains supported by this agent. At least one must be specified.", min_length=1, ), ] diff --git a/src/adcp/types/generated_poc/signals/activate_signal_request.py b/src/adcp/types/generated_poc/signals/activate_signal_request.py index cf9eea76..91610a7a 100644 --- a/src/adcp/types/generated_poc/signals/activate_signal_request.py +++ b/src/adcp/types/generated_poc/signals/activate_signal_request.py @@ -16,17 +16,17 @@ class ActivateSignalRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None deployments: Annotated[ list[destination.Destination], Field( - description='Target deployment(s) for activation. If the authenticated caller matches one of these deployment targets, activation keys will be included in the response.', + description="Target deployment(s) for activation. If the authenticated caller matches one of these deployment targets, activation keys will be included in the response.", min_length=1, ), ] ext: ext_1.ExtensionObject | None = None signal_agent_segment_id: Annotated[ - str, Field(description='The universal identifier for the signal to activate') + str, Field(description="The universal identifier for the signal to activate") ] diff --git a/src/adcp/types/generated_poc/signals/activate_signal_response.py b/src/adcp/types/generated_poc/signals/activate_signal_response.py index 0ea7f6de..9d9e0629 100644 --- a/src/adcp/types/generated_poc/signals/activate_signal_response.py +++ b/src/adcp/types/generated_poc/signals/activate_signal_response.py @@ -16,25 +16,25 @@ class ActivateSignalResponse1(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None deployments: Annotated[ list[deployment.Deployment], - Field(description='Array of deployment results for each deployment target'), + Field(description="Array of deployment results for each deployment target"), ] ext: ext_1.ExtensionObject | None = None class ActivateSignalResponse2(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error], Field( - description='Array of errors explaining why activation failed (e.g., platform connectivity issues, signal definition problems, authentication failures)', + description="Array of errors explaining why activation failed (e.g., platform connectivity issues, signal definition problems, authentication failures)", min_length=1, ), ] @@ -45,7 +45,7 @@ class ActivateSignalResponse(RootModel[ActivateSignalResponse1 | ActivateSignalR root: Annotated[ ActivateSignalResponse1 | ActivateSignalResponse2, Field( - 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.', - title='Activate Signal Response', + 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.", + title="Activate Signal Response", ), ] diff --git a/src/adcp/types/generated_poc/signals/get_signals_request.py b/src/adcp/types/generated_poc/signals/get_signals_request.py index 2e69ba93..7ba5e512 100644 --- a/src/adcp/types/generated_poc/signals/get_signals_request.py +++ b/src/adcp/types/generated_poc/signals/get_signals_request.py @@ -16,20 +16,20 @@ class Country(RootModel[str]): - root: Annotated[str, Field(pattern='^[A-Z]{2}$')] + root: Annotated[str, Field(pattern="^[A-Z]{2}$")] class DeliverTo(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) countries: Annotated[ - list[Country], Field(description='Countries where signals will be used (ISO codes)') + list[Country], Field(description="Countries where signals will be used (ISO codes)") ] deployments: Annotated[ list[destination.Destination], Field( - 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.', + 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.", min_length=1, ), ] @@ -37,17 +37,17 @@ class DeliverTo(AdCPBaseModel): class GetSignalsRequest(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None deliver_to: Annotated[ - DeliverTo, Field(description='Deployment targets where signals need to be activated') + DeliverTo, Field(description="Deployment targets where signals need to be activated") ] ext: ext_1.ExtensionObject | None = None filters: signal_filters.SignalFilters | None = None max_results: Annotated[ - int | None, Field(description='Maximum number of results to return', ge=1) + int | None, Field(description="Maximum number of results to return", ge=1) ] = None signal_spec: Annotated[ - str, Field(description='Natural language description of the desired signals') + str, Field(description="Natural language description of the desired signals") ] diff --git a/src/adcp/types/generated_poc/signals/get_signals_response.py b/src/adcp/types/generated_poc/signals/get_signals_response.py index dffdbdd8..4eb3a975 100644 --- a/src/adcp/types/generated_poc/signals/get_signals_response.py +++ b/src/adcp/types/generated_poc/signals/get_signals_response.py @@ -17,42 +17,42 @@ class Pricing(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) - cpm: Annotated[float, Field(description='Cost per thousand impressions', ge=0.0)] - currency: Annotated[str, Field(description='Currency code', pattern='^[A-Z]{3}$')] + cpm: Annotated[float, Field(description="Cost per thousand impressions", ge=0.0)] + currency: Annotated[str, Field(description="Currency code", pattern="^[A-Z]{3}$")] class Signal(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) coverage_percentage: Annotated[ - float, Field(description='Percentage of audience coverage', ge=0.0, le=100.0) + float, Field(description="Percentage of audience coverage", ge=0.0, le=100.0) ] - data_provider: Annotated[str, Field(description='Name of the data provider')] + data_provider: Annotated[str, Field(description="Name of the data provider")] deployments: Annotated[ - list[deployment.Deployment], Field(description='Array of deployment targets') + list[deployment.Deployment], Field(description="Array of deployment targets") ] - description: Annotated[str, Field(description='Detailed signal description')] - name: Annotated[str, Field(description='Human-readable signal name')] - pricing: Annotated[Pricing, Field(description='Pricing information')] - signal_agent_segment_id: Annotated[str, Field(description='Unique identifier for the signal')] + description: Annotated[str, Field(description="Detailed signal description")] + name: Annotated[str, Field(description="Human-readable signal name")] + pricing: Annotated[Pricing, Field(description="Pricing information")] + signal_agent_segment_id: Annotated[str, Field(description="Unique identifier for the signal")] signal_type: Annotated[ - signal_catalog_type.SignalCatalogType, Field(description='Type of signal') + signal_catalog_type.SignalCatalogType, Field(description="Type of signal") ] class GetSignalsResponse(AdCPBaseModel): model_config = ConfigDict( - extra='allow', + extra="allow", ) context: context_1.ContextObject | None = None errors: Annotated[ list[error.Error] | None, Field( - description='Task-specific errors and warnings (e.g., signal discovery or pricing issues)' + description="Task-specific errors and warnings (e.g., signal discovery or pricing issues)" ), ] = None ext: ext_1.ExtensionObject | None = None - signals: Annotated[list[Signal], Field(description='Array of matching signals')] + signals: Annotated[list[Signal], Field(description="Array of matching signals")] diff --git a/tests/test_cli.py b/tests/test_cli.py index 7310abce..b0845e2b 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -366,8 +366,8 @@ class TestDeprecatedFieldWarnings: def test_check_deprecated_fields_warns_on_assets_required(self, capsys): """Should warn when response contains deprecated assets_required field.""" + from adcp import Format, FormatCategory, FormatId from adcp.__main__ import _check_deprecated_fields - from adcp import Format, FormatId, FormatCategory fmt = Format( format_id=FormatId(agent_url="https://test.com", id="test"), @@ -385,15 +385,20 @@ def test_check_deprecated_fields_warns_on_assets_required(self, capsys): def test_check_deprecated_fields_no_warning_for_new_assets(self, capsys): """Should not warn when using new assets field.""" + from adcp import Format, FormatCategory, FormatId from adcp.__main__ import _check_deprecated_fields - from adcp import Format, FormatId, FormatCategory fmt = Format( format_id=FormatId(agent_url="https://test.com", id="test"), name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "img", "asset_type": "image", "item_type": "individual", "required": True}, + { + "asset_id": "img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, ], ) @@ -411,8 +416,8 @@ def test_check_deprecated_fields_handles_none(self, capsys): def test_check_deprecated_fields_handles_list(self, capsys): """Should check items in a list.""" + from adcp import Format, FormatCategory, FormatId from adcp.__main__ import _check_deprecated_fields - from adcp import Format, FormatId, FormatCategory formats = [ Format( diff --git a/tests/test_discriminated_unions.py b/tests/test_discriminated_unions.py index 0e7e1772..2addc7bf 100644 --- a/tests/test_discriminated_unions.py +++ b/tests/test_discriminated_unions.py @@ -819,8 +819,8 @@ def test_shared_schema_prevents_collision(self): # The shared schema is the canonical definition in core/ assert PropertyTag is property_tag.PropertyTag - # Both adagents.py and publisher_property_selector.py should import from core.property_tag module - # (not define their own) + # Both adagents.py and publisher_property_selector.py should import from + # core.property_tag module (not define their own) import inspect import adcp.types.generated_poc.adagents as adagents_module diff --git a/tests/test_format_assets.py b/tests/test_format_assets.py index e0ce0738..0eb97c94 100644 --- a/tests/test_format_assets.py +++ b/tests/test_format_assets.py @@ -4,19 +4,18 @@ handling the migration from deprecated `assets_required` to new `assets` field. """ -import pytest -from adcp import Format, FormatId, FormatCategory +from adcp import Format, FormatCategory, FormatId from adcp.utils.format_assets import ( + get_asset_count, get_format_assets, - normalize_assets_required, - get_required_assets, - get_optional_assets, get_individual_assets, + get_optional_assets, get_repeatable_groups, - uses_deprecated_assets_field, - get_asset_count, + get_required_assets, has_assets, + normalize_assets_required, + uses_deprecated_assets_field, ) @@ -45,7 +44,12 @@ def test_prefers_new_assets_field(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "new_img", "asset_type": "image", "item_type": "individual", "required": True}, + { + "asset_id": "new_img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, ], assets_required=[ {"asset_id": "old_img", "asset_type": "image", "item_type": "individual"}, @@ -145,9 +149,24 @@ def test_filters_to_required_only(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "required_img", "asset_type": "image", "item_type": "individual", "required": True}, - {"asset_id": "optional_logo", "asset_type": "image", "item_type": "individual", "required": False}, - {"asset_id": "required_url", "asset_type": "url", "item_type": "individual", "required": True}, + { + "asset_id": "required_img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, + { + "asset_id": "optional_logo", + "asset_type": "image", + "item_type": "individual", + "required": False, + }, + { + "asset_id": "required_url", + "asset_type": "url", + "item_type": "individual", + "required": True, + }, ], ) required = get_required_assets(fmt) @@ -182,8 +201,18 @@ def test_filters_to_optional_only(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "required_img", "asset_type": "image", "item_type": "individual", "required": True}, - {"asset_id": "optional_logo", "asset_type": "image", "item_type": "individual", "required": False}, + { + "asset_id": "required_img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, + { + "asset_id": "optional_logo", + "asset_type": "image", + "item_type": "individual", + "required": False, + }, ], ) optional = get_optional_assets(fmt) @@ -214,7 +243,12 @@ def test_filters_to_individual_only(self): name="Carousel", type=FormatCategory.display, assets=[ - {"asset_id": "headline", "asset_type": "text", "item_type": "individual", "required": True}, + { + "asset_id": "headline", + "asset_type": "text", + "item_type": "individual", + "required": True, + }, { "asset_group_id": "product", "item_type": "repeatable_group", @@ -240,7 +274,12 @@ def test_filters_to_groups_only(self): name="Carousel", type=FormatCategory.display, assets=[ - {"asset_id": "headline", "asset_type": "text", "item_type": "individual", "required": True}, + { + "asset_id": "headline", + "asset_type": "text", + "item_type": "individual", + "required": True, + }, { "asset_group_id": "product", "item_type": "repeatable_group", @@ -278,7 +317,12 @@ def test_false_when_using_new_assets(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "img", "asset_type": "image", "item_type": "individual", "required": True}, + { + "asset_id": "img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, ], ) assert uses_deprecated_assets_field(fmt) is False @@ -303,8 +347,18 @@ def test_counts_all_assets(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "img1", "asset_type": "image", "item_type": "individual", "required": True}, - {"asset_id": "img2", "asset_type": "image", "item_type": "individual", "required": False}, + { + "asset_id": "img1", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, + { + "asset_id": "img2", + "asset_type": "image", + "item_type": "individual", + "required": False, + }, ], ) assert get_asset_count(fmt) == 2 @@ -329,7 +383,12 @@ def test_true_when_has_assets(self): name="Test", type=FormatCategory.display, assets=[ - {"asset_id": "img", "asset_type": "image", "item_type": "individual", "required": True}, + { + "asset_id": "img", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, ], ) assert has_assets(fmt) is True @@ -350,16 +409,17 @@ class TestPublicImports: def test_can_import_from_adcp(self): """Should be able to import utilities from main adcp package.""" from adcp import ( + get_asset_count, get_format_assets, - get_required_assets, - get_optional_assets, get_individual_assets, + get_optional_assets, get_repeatable_groups, - uses_deprecated_assets_field, - normalize_assets_required, - get_asset_count, + get_required_assets, has_assets, + normalize_assets_required, + uses_deprecated_assets_field, ) + # All should be callable assert callable(get_format_assets) assert callable(get_required_assets) diff --git a/tests/test_preview_html.py b/tests/test_preview_html.py index 4fca7203..1498a188 100644 --- a/tests/test_preview_html.py +++ b/tests/test_preview_html.py @@ -499,9 +499,24 @@ def test_create_sample_manifest_for_format_with_new_assets_field(): description="Standard banner", type="display", assets=[ - {"asset_id": "banner_image", "asset_type": "image", "item_type": "individual", "required": True}, - {"asset_id": "logo", "asset_type": "image", "item_type": "individual", "required": False}, - {"asset_id": "cta_url", "asset_type": "url", "item_type": "individual", "required": True}, + { + "asset_id": "banner_image", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, + { + "asset_id": "logo", + "asset_type": "image", + "item_type": "individual", + "required": False, + }, + { + "asset_id": "cta_url", + "asset_type": "url", + "item_type": "individual", + "required": True, + }, ], ) @@ -524,7 +539,12 @@ def test_create_sample_manifest_prefers_assets_over_assets_required(): type="display", # Both fields present - should prefer assets assets=[ - {"asset_id": "new_image", "asset_type": "image", "item_type": "individual", "required": True}, + { + "asset_id": "new_image", + "asset_type": "image", + "item_type": "individual", + "required": True, + }, ], assets_required=[ {"asset_id": "old_image", "asset_type": "image", "item_type": "individual"}, diff --git a/tests/test_protocols.py b/tests/test_protocols.py index 9df746b3..58c1e817 100644 --- a/tests/test_protocols.py +++ b/tests/test_protocols.py @@ -8,13 +8,13 @@ AgentCard, Artifact, DataPart, - Message, SendMessageSuccessResponse, Task, - TaskState, - TaskStatus as A2ATaskStatus, TextPart, ) +from a2a.types import ( + TaskStatus as A2ATaskStatus, +) from adcp.protocols.a2a import A2AAdapter from adcp.protocols.mcp import MCPAdapter @@ -843,4 +843,3 @@ async def test_cleanup_handles_exception_group_with_cancelled_error(self, mcp_co mock_exit_stack.aclose.assert_called_once() assert adapter._exit_stack is None assert adapter._session is None - diff --git a/tests/test_public_api.py b/tests/test_public_api.py index 90a5c6f4..7d3a4a0a 100644 --- a/tests/test_public_api.py +++ b/tests/test_public_api.py @@ -320,9 +320,7 @@ def test_list_creative_formats_request_has_filter_params(): ] for field_name in expected_fields: - assert field_name in model_fields, ( - f"ListCreativeFormatsRequest missing field: {field_name}" - ) + assert field_name in model_fields, f"ListCreativeFormatsRequest missing field: {field_name}" def test_list_creative_formats_request_filter_params_types(): diff --git a/tests/test_response_str.py b/tests/test_response_str.py index 36dab723..95be9e59 100644 --- a/tests/test_response_str.py +++ b/tests/test_response_str.py @@ -117,9 +117,7 @@ class TestListCreativesResponseMessage: def test_singular_creative(self): """Single creative uses singular form.""" - response = ListCreativesResponse.model_construct( - creatives=[{"creative_id": "c1"}] - ) + response = ListCreativesResponse.model_construct(creatives=[{"creative_id": "c1"}]) assert response.summary() == "Found 1 creative in the system." def test_multiple_creatives(self): @@ -222,9 +220,7 @@ class TestActivateSignalResponseMessage: def test_success(self): """Success message is simple confirmation.""" - response = ActivateSignalResponse1.model_construct( - activation_status="active" - ) + response = ActivateSignalResponse1.model_construct(activation_status="active") assert response.summary() == "Signal activated successfully." def test_error(self): @@ -317,9 +313,7 @@ class TestProvidePerformanceFeedbackResponseMessage: def test_success(self): """Success message is simple confirmation.""" - response = ProvidePerformanceFeedbackResponse1.model_construct( - acknowledged=True - ) + response = ProvidePerformanceFeedbackResponse1.model_construct(acknowledged=True) assert response.summary() == "Performance feedback recorded successfully." def test_error(self): diff --git a/tests/test_webhook_handling.py b/tests/test_webhook_handling.py index 0b4dd8b1..ead01b20 100644 --- a/tests/test_webhook_handling.py +++ b/tests/test_webhook_handling.py @@ -4,10 +4,22 @@ import json from datetime import datetime, timezone -from unittest.mock import MagicMock, patch import pytest -from a2a.types import Artifact, DataPart, Message, Part, Role, Task, TaskState, TaskStatus as A2ATaskStatus, TaskStatusUpdateEvent, TextPart +from a2a.types import ( + Artifact, + DataPart, + Message, + Part, + Role, + Task, + TaskState, + TaskStatusUpdateEvent, + TextPart, +) +from a2a.types import ( + TaskStatus as A2ATaskStatus, +) from adcp.client import ADCPClient from adcp.exceptions import ADCPWebhookSignatureError @@ -35,11 +47,7 @@ async def test_mcp_webhook_completed_success(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "media_buy_id": "mb_123", - "buyer_ref": "ref_123", - "packages": [] - }, + "result": {"media_buy_id": "mb_123", "buyer_ref": "ref_123", "packages": []}, "message": "Media buy created successfully", } @@ -61,9 +69,7 @@ async def test_mcp_webhook_completed_with_errors(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "errors": [{"code": "NOT_FOUND", "message": "No matching inventory"}] - }, + "result": {"errors": [{"code": "NOT_FOUND", "message": "No matching inventory"}]}, "message": "No matching inventory found", } @@ -161,11 +167,7 @@ async def test_mcp_webhook_signature_verification_valid(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "media_buy_id": "mb_333", - "buyer_ref": "ref_333", - "packages": [] - }, + "result": {"media_buy_id": "mb_333", "buyer_ref": "ref_333", "packages": []}, } # Generate valid signature using {timestamp}.{payload} format @@ -174,12 +176,10 @@ async def test_mcp_webhook_signature_verification_valid(self): import hmac header_timestamp = "2025-01-15T10:00:00Z" - payload_bytes = json.dumps(payload, separators=(",", ":"), sort_keys=False).encode( - "utf-8" - ) + payload_bytes = json.dumps(payload, separators=(",", ":"), sort_keys=False).encode("utf-8") signed_message = f"{header_timestamp}.{payload_bytes.decode('utf-8')}" signature = hmac.new( - "test_secret".encode("utf-8"), signed_message.encode("utf-8"), hashlib.sha256 + b"test_secret", signed_message.encode("utf-8"), hashlib.sha256 ).hexdigest() result = await self.client.handle_webhook( @@ -200,11 +200,7 @@ async def test_mcp_webhook_signature_verification_invalid(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "media_buy_id": "mb_444", - "buyer_ref": "ref_444", - "packages": [] - }, + "result": {"media_buy_id": "mb_444", "buyer_ref": "ref_444", "packages": []}, } with pytest.raises(ADCPWebhookSignatureError): @@ -246,23 +242,21 @@ def setup_method(self): @pytest.mark.asyncio async def test_a2a_webhook_completed_success(self): """Test A2A Task with completed status and valid AdCP payload.""" - media_buy_data = { - "media_buy_id": "mb_123", - "buyer_ref": "ref_123", - "packages": [] - } + media_buy_data = {"media_buy_id": "mb_123", "buyer_ref": "ref_123", "packages": []} task = Task( id="task_123", context_id="ctx_456", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="artifact_123", parts=[ Part(root=DataPart(data=media_buy_data)), Part(root=TextPart(text="Media buy created")), - ] + ], ) ], ) @@ -287,12 +281,11 @@ async def test_a2a_webhook_completed_with_errors(self): task = Task( id="task_456", context_id="ctx_789", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ - Artifact( - artifact_id="test_artifact", - parts=[Part(root=DataPart(data=error_data))] - ) + Artifact(artifact_id="test_artifact", parts=[Part(root=DataPart(data=error_data))]) ], ) @@ -321,13 +314,11 @@ async def test_a2a_webhook_failed_status(self): status=A2ATaskStatus(state="failed", timestamp=datetime.now(timezone.utc).isoformat()), artifacts=[ Artifact( - artifact_id="test_artifact", - parts=[ Part(root=DataPart(data=error_data)), Part(root=TextPart(text="Task failed due to internal error")), - ] + ], ) ], ) @@ -352,7 +343,7 @@ async def test_a2a_webhook_working_status(self): artifact_id="test_artifact", parts=[ Part(root=TextPart(text="Processing request...")), - ] + ], ) ], ) @@ -379,13 +370,11 @@ async def test_a2a_webhook_input_required_status(self): ), artifacts=[ Artifact( - artifact_id="test_artifact", - parts=[ Part(root=DataPart(data=input_data)), Part(root=TextPart(text="Campaign budget $150K requires VP approval")), - ] + ], ) ], ) @@ -404,7 +393,9 @@ async def test_a2a_webhook_missing_artifacts(self): task = Task( id="task_333", context_id="ctx_444", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[], # Empty artifacts ) @@ -421,15 +412,13 @@ async def test_a2a_webhook_missing_data_part(self): task = Task( id="task_444", context_id="ctx_555", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( - artifact_id="test_artifact", - - parts=[ - Part(root=TextPart(text="Only text, no data")) # Only TextPart - ] + parts=[Part(root=TextPart(text="Only text, no data"))], # Only TextPart ) ], ) @@ -450,11 +439,12 @@ async def test_a2a_webhook_malformed_adcp_data(self): task = Task( id="task_555", context_id="ctx_666", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( - artifact_id="test_artifact", - parts=[Part(root=DataPart(data=minimal_data))] + artifact_id="test_artifact", parts=[Part(root=DataPart(data=minimal_data))] ) ], ) @@ -590,17 +580,23 @@ async def test_a2a_webhook_signature_not_required(self): task = Task( id="task_666", context_id="ctx_777", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="test_artifact", parts=[ - Part(root=DataPart(data={ - "media_buy_id": "mb_666", - "buyer_ref": "ref_666", - "packages": [] - })) - ] + Part( + root=DataPart( + data={ + "media_buy_id": "mb_666", + "buyer_ref": "ref_666", + "packages": [], + } + ) + ) + ], ) ], ) @@ -642,11 +638,7 @@ async def test_type_detection_mcp_dict(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "media_buy_id": "mb_mcp", - "buyer_ref": "ref_mcp", - "packages": [] - }, + "result": {"media_buy_id": "mb_mcp", "buyer_ref": "ref_mcp", "packages": []}, } result = await self.mcp_client.handle_webhook( @@ -662,15 +654,23 @@ async def test_type_detection_a2a_task(self): task = Task( id="task_a2a", context_id="ctx_a2a", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="test_artifact", - parts=[Part(root=DataPart(data={ - "media_buy_id": "mb_a2a", - "buyer_ref": "ref_a2a", - "packages": [] - }))] + parts=[ + Part( + root=DataPart( + data={ + "media_buy_id": "mb_a2a", + "buyer_ref": "ref_a2a", + "packages": [], + } + ) + ) + ], ) ], ) @@ -710,11 +710,7 @@ async def test_type_detection_a2a_taskstatusupdateevent(self): @pytest.mark.asyncio async def test_consistent_result_format(self): """Verify MCP and A2A return identical TaskResult structure.""" - media_buy_data = { - "media_buy_id": "mb_test", - "buyer_ref": "ref_test", - "packages": [] - } + media_buy_data = {"media_buy_id": "mb_test", "buyer_ref": "ref_test", "packages": []} # MCP webhook mcp_payload = { @@ -729,13 +725,12 @@ async def test_consistent_result_format(self): a2a_task = Task( id="task_2", context_id="ctx_2", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( - artifact_id="test_artifact", - parts=[ - Part(root=DataPart(data=media_buy_data)) - ] + artifact_id="test_artifact", parts=[Part(root=DataPart(data=media_buy_data))] ) ], ) @@ -764,11 +759,7 @@ def test_extract_from_mcp_webhook(self): "task_type": "create_media_buy", "status": "completed", "timestamp": "2025-01-15T10:00:00Z", - "result": { - "media_buy_id": "mb_123", - "buyer_ref": "ref_123", - "packages": [] - }, + "result": {"media_buy_id": "mb_123", "buyer_ref": "ref_123", "packages": []}, } result = extract_webhook_result_data(mcp_payload) @@ -780,29 +771,27 @@ def test_extract_from_mcp_webhook(self): def test_extract_from_a2a_task_webhook(self): """Test extracting result from A2A Task webhook payload.""" - media_buy_data = { - "media_buy_id": "mb_456", - "buyer_ref": "ref_456", - "packages": [] - } + media_buy_data = {"media_buy_id": "mb_456", "buyer_ref": "ref_456", "packages": []} task = Task( id="task_456", context_id="ctx_456", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="artifact_456", parts=[ Part(root=DataPart(data=media_buy_data)), Part(root=TextPart(text="Media buy created")), - ] + ], ) ], ) # Convert to dict (simulating JSON deserialization) - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) assert result is not None @@ -835,7 +824,7 @@ def test_extract_from_a2a_taskstatusupdateevent_webhook(self): ) # Convert to dict (simulating JSON deserialization) - event_dict = event.model_dump(mode='json') + event_dict = event.model_dump(mode="json") result = extract_webhook_result_data(event_dict) assert result is not None @@ -845,27 +834,22 @@ def test_extract_from_a2a_taskstatusupdateevent_webhook(self): def test_extract_from_a2a_with_response_wrapper(self): """Test extracting result from A2A payload with {"response": {...}} wrapper.""" wrapped_data = { - "response": { - "media_buy_id": "mb_789", - "buyer_ref": "ref_789", - "packages": [] - } + "response": {"media_buy_id": "mb_789", "buyer_ref": "ref_789", "packages": []} } task = Task( id="task_789", context_id="ctx_789", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ - Artifact( - artifact_id="artifact_789", - parts=[Part(root=DataPart(data=wrapped_data))] - ) + Artifact(artifact_id="artifact_789", parts=[Part(root=DataPart(data=wrapped_data))]) ], ) # Convert to dict - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) # Should unwrap the response wrapper @@ -892,11 +876,13 @@ def test_extract_from_a2a_with_empty_artifacts(self): task = Task( id="task_222", context_id="ctx_222", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[], ) - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) assert result is None @@ -906,16 +892,18 @@ def test_extract_from_a2a_with_no_data_part(self): task = Task( id="task_333", context_id="ctx_333", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="artifact_333", - parts=[Part(root=TextPart(text="Only text, no data"))] + parts=[Part(root=TextPart(text="Only text, no data"))], ) ], ) - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) assert result is None @@ -928,20 +916,16 @@ def test_extract_from_a2a_with_multiple_artifacts(self): task = Task( id="task_444", context_id="ctx_444", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ - Artifact( - artifact_id="artifact_old", - parts=[Part(root=DataPart(data=old_data))] - ), - Artifact( - artifact_id="artifact_new", - parts=[Part(root=DataPart(data=new_data))] - ), + Artifact(artifact_id="artifact_old", parts=[Part(root=DataPart(data=old_data))]), + Artifact(artifact_id="artifact_new", parts=[Part(root=DataPart(data=new_data))]), ], ) - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) # Should use last artifact @@ -961,7 +945,7 @@ def test_extract_from_a2a_taskstatusupdateevent_with_no_message(self): final=False, ) - event_dict = event.model_dump(mode='json') + event_dict = event.model_dump(mode="json") result = extract_webhook_result_data(event_dict) assert result is None @@ -983,24 +967,23 @@ def test_extract_from_mcp_with_missing_result_field(self): def test_extract_from_a2a_with_nested_response_wrapper(self): """Test that only single-key {"response": {...}} wrapper is unwrapped.""" # Data with response wrapper but also other keys (should NOT unwrap) - data_with_extra_keys = { - "response": {"media_buy_id": "mb_777"}, - "other_key": "value" - } + data_with_extra_keys = {"response": {"media_buy_id": "mb_777"}, "other_key": "value"} task = Task( id="task_777", context_id="ctx_777", - status=A2ATaskStatus(state="completed", timestamp=datetime.now(timezone.utc).isoformat()), + status=A2ATaskStatus( + state="completed", timestamp=datetime.now(timezone.utc).isoformat() + ), artifacts=[ Artifact( artifact_id="artifact_777", - parts=[Part(root=DataPart(data=data_with_extra_keys))] + parts=[Part(root=DataPart(data=data_with_extra_keys))], ) ], ) - task_dict = task.model_dump(mode='json') + task_dict = task.model_dump(mode="json") result = extract_webhook_result_data(task_dict) # Should NOT unwrap (has multiple keys)