Skip to content

Commit 346689d

Browse files
bokelleyclaude
andauthored
refactor: remove direct generated_poc imports (#65)
* refactor: remove direct generated_poc imports Replace all direct imports from adcp.types.generated_poc with imports from adcp.types._generated. This enforces the public API boundary and prevents downstream users from depending on internal implementation details. Changes: - Update consolidate_exports.py to handle Package name collision by exporting both types with qualified names (_PackageFromPackage, _PackageFromCreateMediaBuyResponse) - Migrate client.py to import TaskStatus from _generated - Migrate aliases.py to import all types from _generated - Migrate stable.py to import Package from _generated using qualified name - Regenerate _generated.py with collision-resolved exports This ensures that: 1. generated_poc directory remains internal (not part of public API) 2. All type consolidation happens in _generated.py 3. Only stable.py and aliases.py provide public type exports 4. Users import from adcp or adcp.types.stable, not internal modules 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: enforce import boundary - only stable.py/aliases.py may use _generated Source code was incorrectly importing from _generated.py, making it just as brittle as importing from generated_poc. This fixes the architecture to properly enforce the public API boundary. Changes: - Add WebhookPayload to stable.py exports - Change client.py, __init__.py, simple.py to import from stable.py - Change preview_cache.py to use semantic aliases (PreviewCreativeFormatRequest) - Document import architecture rules in CLAUDE.md Import architecture (enforced): ``` generated_poc/*.py (internal) ↓ _generated.py (internal consolidation) ↓ stable.py + aliases.py (ONLY files that import from _generated) ↓ All other source code (imports from stable/aliases only) ``` This prevents brittleness from: - Collision-resolution qualifiers (_PackageFromX) - Numbered discriminated union types (Response1, Response2) - Schema evolution changes in generated files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: sort imports to pass ruff linter Ruff check was failing due to unsorted imports. Fixed by running ruff --fix. Changes: - Sort imports in __init__.py according to isort rules - Sort imports in client.py - Sort imports in aliases.py 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: remove review artifacts from commit history The ARCHITECTURE_REVIEW.md, PR65_EVALUATION.md, and type_collision_demo.py were created by review agents as deliverables but shouldn't be part of the repository. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: resolve PublisherProperties name collision with qualified exports The consolidation script now handles PublisherProperties name collisions between adagents and product modules by exporting both with qualified names: - _PublisherPropertiesFromProduct (used for semantic aliases) - _PublisherPropertiesFromAdagents - _PublisherProperties4FromProduct (by_id discriminator) - _PublisherProperties5FromProduct (by_tag discriminator) Updated aliases.py and tests to use qualified names from _generated.py instead of importing directly from generated_poc modules, enforcing proper import boundaries. All 295 tests pass. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: adopt shared PublisherPropertySelector schema from upstream After upstream PR #219 merged, the PublisherProperties type is now defined in a shared publisher-property-selector.json schema with all 3 variants (all, by_id, by_tag). Changes: - Synced schemas from upstream (now includes publisher-property-selector.json) - Regenerated types (PublisherPropertySelector1/2/3 from shared schema) - Removed PublisherProperties from collision handling in consolidate_exports.py - Updated aliases.py to use PublisherPropertySelector types - Updated tests to reference shared types instead of module-specific variants Benefits: - Single source of truth for publisher property selection - No more name collisions between adagents and product modules - Simplified type system with cleaner exports - DRY schema definitions maintained upstream All 295 tests pass. Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9f63373 commit 346689d

19 files changed

+728
-712
lines changed

CLAUDE.md

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,84 @@ FormatId = str
1717
PackageRequest = dict[str, Any]
1818
```
1919

20-
**Stable Public API Layer**
20+
**Stable Public API Layer - Import Architecture**
2121

22-
**CRITICAL**: The `generated_poc` directory is internal implementation. **Never import directly from it**.
22+
**CRITICAL**: Both `generated_poc/` and `_generated.py` are internal implementation. Source code must ONLY import from `stable.py` or `aliases.py`.
2323

24-
Generated types in `src/adcp/types/generated_poc/` may have:
25-
- Numbered suffixes (e.g., `BrandManifest1`, `BrandManifest2`) due to schema evolution
26-
- Structural changes between minor versions
27-
- Files added/removed as schemas evolve
24+
### Import Architecture
2825

29-
**Always use the stable API:**
26+
The type system has a strict layering to prevent brittleness:
27+
28+
```
29+
generated_poc/*.py (internal, auto-generated from schemas)
30+
31+
_generated.py (internal consolidation, handles name collisions)
32+
33+
stable.py (public API for base types) + aliases.py (public API for discriminated unions)
34+
35+
__init__.py (user-facing exports)
36+
```
37+
38+
### Import Rules for Source Code
39+
40+
**✅ CORRECT - Public API only:**
41+
```python
42+
# For base types (requests, responses, domain models)
43+
from adcp.types.stable import (
44+
GetProductsRequest,
45+
GetProductsResponse,
46+
Product,
47+
Package,
48+
BrandManifest,
49+
)
50+
51+
# For semantic aliases (discriminated unions)
52+
from adcp.types.aliases import (
53+
CreateMediaBuySuccessResponse,
54+
CreateMediaBuyErrorResponse,
55+
PreviewCreativeFormatRequest,
56+
)
57+
58+
# Or from main package
59+
from adcp import Product, CreateMediaBuySuccessResponse
60+
```
61+
62+
**❌ WRONG - Internal implementation (brittle):**
3063
```python
31-
# ✅ CORRECT - Stable public API
32-
from adcp.types import BrandManifest, Product, CpmFixedRatePricingOption
33-
from adcp.types.stable import BrandManifest, Product
64+
# Never import from _generated - it's internal consolidation
65+
from adcp.types._generated import GetProductsRequest
3466

35-
# ❌ WRONG - Internal generated types (will break)
36-
from adcp.types.generated_poc.brand_manifest import BrandManifest1
37-
from adcp.types._generated import BrandManifest1
67+
# Never import from generated_poc - it's internal generated code
68+
from adcp.types.generated_poc.product import Product
69+
70+
# Never import numbered types directly - use semantic aliases
71+
from adcp.types._generated import CreateMediaBuyResponse1
3872
```
3973

40-
The stable API (`src/adcp/types/stable.py`) provides:
41-
1. **Clean names** - `BrandManifest` not `BrandManifest1`
42-
2. **Stability** - Aliases are updated when schemas evolve
43-
3. **Versioning** - Breaking changes require major version bumps
44-
4. **Deprecation warnings** - Direct `generated_poc` imports trigger warnings
74+
### Why This Matters
75+
76+
1. **`generated_poc/`** may have:
77+
- Numbered suffixes (e.g., `Response1`, `Response2`)
78+
- Files added/removed as schemas evolve
79+
- Name collisions between modules
80+
81+
2. **`_generated.py`** may have:
82+
- Collision-resolution qualifiers (e.g., `_PackageFromPackage`)
83+
- Internal consolidation logic
84+
- Changes when collision handling evolves
85+
86+
3. **`stable.py` and `aliases.py`** provide:
87+
- Clean, semantic names
88+
- Stability guarantees within major versions
89+
- Explicit public API
90+
91+
### Special Cases
92+
93+
**Only `stable.py` and `aliases.py` may import from `_generated.py`:**
94+
- `stable.py`: Imports base types and re-exports with clean names
95+
- `aliases.py`: Imports numbered discriminated union types and creates semantic aliases
96+
97+
**All other source files must import from `stable.py` or `aliases.py`.**
4598

4699
**NEVER Modify Generated Files Directly**
47100

schemas/cache/.hashes.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/index.json": "eed524f6ca3b7b8981035a74f3eaf339da6fadab85e4af9196c1c7c4d5150095",
3-
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/adagents.json": "bd0e7cd9189b191d827a3ab7fb9d4f9ef4913377c816c5aa27af30bfd20d3451",
2+
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/index.json": "46f68f0e55d63361c0eda1cc7ffff4f25c9416467dd3a04db2cca0973f086b7d",
3+
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/adagents.json": "f32e3778a454b7ae65f42952906f06466008bfd1208b83729e14d5f2164902d5",
44
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/activation-key.json": "bb9c20c6200b651ce6db89f7160be60b9845dbbb4390a13363ea5b82c1c3c786",
55
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/asset-type.json": "a61ac8e14a61adef64d10d6ab39c204d703c087f29efa45c69c527988c93cd3d",
66
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/assets/audio-asset.json": "e25d688d22c8b130d9d1a2a09f9aa462cb7a5c83db6eea6f328cd937f8625a3f",
@@ -34,11 +34,12 @@
3434
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/performance-feedback.json": "80384474042b6cda08b1128859143ec5822d6dcc907ba1fa3ecf81719e7644a7",
3535
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/placement.json": "ea814df6d878232bfdb1249fe199a1e32ec18598b7d3e3c57324d6e6120d9cf8",
3636
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/pricing-option.json": "cfaeff3d4fc49e0d3ae76364e246b3b7a772ef12cbda65b1cff400ab1f841bfa",
37-
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/product.json": "f3ef04e850cb61c2ba86e05da1d5a352b63031ddbb42fbdffbbbd6c8432ad5c5",
37+
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/product.json": "e1b4faa9029bd06baa537fbf534993e7830b1bdc2241279dea4806c134cea50d",
3838
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/promoted-offerings.json": "d8b4b92db0e2debc5c0ddbc0a8ff673f258f0bbc0348737df61be20a25827077",
3939
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/promoted-products.json": "77773b1dce91b219ec5043c091eb2977a82ba301e03aead3868ba704e625379e",
4040
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/property.json": "510458c96a93deb90d9fa3a4dfc11b63c113755dbec3de386690f6838213bc84",
4141
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/protocol-envelope.json": "c6096b4ed4330c5e2045989bfd5cdc64fa6587cf8b0d1d2c19e33c7434cdacb8",
42+
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/publisher-property-selector.json": "3e4870d0446a5825c16365a99d49932517223c1d9d3d46a4fbf413d377ed43dd",
4243
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/push-notification-config.json": "be2af5dbf7d398c958e59c70ab61a845e4a7d1f1e076412589d06d53454b64b0",
4344
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/reporting-capabilities.json": "c463c8d512c17b8ac7afde34d782b5e5f700ed9cf73a52992a328f85ad24d568",
4445
"https://raw.githubusercontent.com/adcontextprotocol/adcp/main/static/schemas/v1/core/response.json": "0ac624a30da08e1aa90d2a9379f8c1ed29b704c3f5399224b9684672d3df9723",

schemas/cache/1.0.0/adagents.json

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@
318318
"properties": {
319319
"description": "Specific properties this agent is authorized for (alternative to property_ids/property_tags)",
320320
"items": {
321-
"$ref": "property.json"
321+
"$ref": "/schemas/v1/core/property.json"
322322
},
323323
"minItems": 1,
324324
"type": "array"
@@ -354,68 +354,7 @@
354354
"publisher_properties": {
355355
"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",
356356
"items": {
357-
"oneOf": [
358-
{
359-
"additionalProperties": false,
360-
"properties": {
361-
"property_ids": {
362-
"description": "Specific property IDs from the publisher's adagents.json properties array",
363-
"items": {
364-
"pattern": "^[a-z0-9_]+$",
365-
"type": "string"
366-
},
367-
"minItems": 1,
368-
"type": "array"
369-
},
370-
"publisher_domain": {
371-
"description": "Domain where the publisher's adagents.json is hosted (e.g., 'cnn.com')",
372-
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$",
373-
"type": "string"
374-
},
375-
"selection_type": {
376-
"const": "by_id",
377-
"description": "Discriminator indicating selection by specific property IDs",
378-
"type": "string"
379-
}
380-
},
381-
"required": [
382-
"publisher_domain",
383-
"selection_type",
384-
"property_ids"
385-
],
386-
"type": "object"
387-
},
388-
{
389-
"additionalProperties": false,
390-
"properties": {
391-
"property_tags": {
392-
"description": "Property tags from the publisher's adagents.json tags. Agent is authorized for all properties with these tags",
393-
"items": {
394-
"pattern": "^[a-z0-9_]+$",
395-
"type": "string"
396-
},
397-
"minItems": 1,
398-
"type": "array"
399-
},
400-
"publisher_domain": {
401-
"description": "Domain where the publisher's adagents.json is hosted (e.g., 'cnn.com')",
402-
"pattern": "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$",
403-
"type": "string"
404-
},
405-
"selection_type": {
406-
"const": "by_tag",
407-
"description": "Discriminator indicating selection by property tags",
408-
"type": "string"
409-
}
410-
},
411-
"required": [
412-
"publisher_domain",
413-
"selection_type",
414-
"property_tags"
415-
],
416-
"type": "object"
417-
}
418-
]
357+
"$ref": "/schemas/v1/core/publisher-property-selector.json"
419358
},
420359
"minItems": 1,
421360
"type": "array"
@@ -487,7 +426,7 @@
487426
"properties": {
488427
"description": "Array of all properties covered by this adagents.json file. Same structure as list_authorized_properties response.",
489428
"items": {
490-
"$ref": "property.json"
429+
"$ref": "/schemas/v1/core/property.json"
491430
},
492431
"minItems": 1,
493432
"type": "array"

0 commit comments

Comments
 (0)