Skip to content

Commit a9b51d0

Browse files
bokelleyclaude
andcommitted
fix: escape quotes and newlines in generated model descriptions
Fixed syntax error in generated.py caused by unescaped quotes and newlines in Field descriptions from JSON schemas. ISSUE: - Multi-line descriptions with quotes broke Python syntax - Line 92 had unterminated string literal causing mypy failure - Descriptions from schemas weren't properly escaped FIX: - Escape double quotes in descriptions: " -> \" - Replace newlines with spaces to keep descriptions single-line - Also escape triple quotes in class-level docstrings - Regenerated all models with proper escaping RESULT: - Python syntax is now valid (py_compile passes) - All 50 generated models are properly formatted - Type checker should now pass in CI 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 38a5174 commit a9b51d0

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

scripts/generate_models_simple.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ def generate_model_for_schema(schema_file: Path) -> str:
3232

3333
# Add description if available
3434
if "description" in schema:
35-
lines.append(f' """{schema["description"]}"""')
35+
# Escape triple quotes in description and normalize whitespace
36+
desc = schema["description"].replace('"""', '\\"\\"\\"').replace('\n', ' ').replace('\r', '')
37+
lines.append(f' """{desc}"""')
3638
lines.append("")
3739

3840
# Add properties
@@ -44,8 +46,11 @@ def generate_model_for_schema(schema_file: Path) -> str:
4446
# Get type
4547
prop_type = get_python_type(prop_schema)
4648

47-
# Get description
49+
# Get description and escape it properly
4850
desc = prop_schema.get("description", "")
51+
# Escape quotes and replace newlines with spaces
52+
if desc:
53+
desc = desc.replace('"', '\\"').replace('\n', ' ').replace('\r', '')
4954

5055
# Check if required
5156
is_required = prop_name in schema.get("required", [])

src/adcp/types/generated.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ class CreativeManifest(BaseModel):
8989

9090
format_id: FormatId = Field(description="Format identifier this manifest is for")
9191
promoted_offering: str | None = Field(None, description="Product name or offering being advertised. Maps to promoted_offerings in create_media_buy request to associate creative with the product being promoted.")
92-
assets: dict[str, Any] = Field(description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets_required array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements.
93-
94-
IMPORTANT: Creative manifest validation MUST be performed in the context of the format specification. The format defines what type each asset_id should be, which eliminates any validation ambiguity.")
92+
assets: dict[str, Any] = Field(description="Map of asset IDs to actual asset content. Each key MUST match an asset_id from the format's assets_required array (e.g., 'banner_image', 'clickthrough_url', 'video_file', 'vast_tag'). The asset_id is the technical identifier used to match assets to format requirements. IMPORTANT: Creative manifest validation MUST be performed in the context of the format specification. The format defines what type each asset_id should be, which eliminates any validation ambiguity.")
9593

9694

9795
class BrandManifest(BaseModel):

0 commit comments

Comments
 (0)