Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion scripts/generate_models_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ def add_custom_implementations(code: str) -> str:
# The simple code generator produces type aliases (e.g., PreviewCreativeRequest = Any)
# for complex schemas that use oneOf. We override them here with proper Pydantic classes
# to maintain type safety and enable batch API support.
# Note: All classes inherit from BaseModel (which is aliased to AdCPBaseModel for exclude_none).


class FormatId(BaseModel):
Expand Down Expand Up @@ -723,7 +724,9 @@ def main():
"import re",
"from typing import Any, Literal",
"",
"from pydantic import BaseModel, ConfigDict, Field, field_validator",
"from pydantic import ConfigDict, Field, field_validator",
"",
"from adcp.types.base import AdCPBaseModel as BaseModel",
"",
"",
"",
Expand Down
2 changes: 2 additions & 0 deletions src/adcp/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

"""Type definitions for AdCP client."""

from adcp.types.base import AdCPBaseModel
from adcp.types.core import (
Activity,
ActivityType,
Expand All @@ -14,6 +15,7 @@
)

__all__ = [
"AdCPBaseModel",
"AgentConfig",
"Protocol",
"TaskResult",
Expand Down
26 changes: 26 additions & 0 deletions src/adcp/types/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from __future__ import annotations

"""Base model for AdCP types with spec-compliant serialization."""

from typing import Any

from pydantic import BaseModel


class AdCPBaseModel(BaseModel):
"""Base model for AdCP types with spec-compliant serialization.

AdCP JSON schemas use additionalProperties: false and do not allow null
for optional fields. Therefore, optional fields must be omitted entirely
when not present (not sent as null).
"""

def model_dump(self, **kwargs: Any) -> dict[str, Any]:
if "exclude_none" not in kwargs:
kwargs["exclude_none"] = True
return super().model_dump(**kwargs)

def model_dump_json(self, **kwargs: Any) -> str:
if "exclude_none" not in kwargs:
kwargs["exclude_none"] = True
return super().model_dump_json(**kwargs)
5 changes: 4 additions & 1 deletion src/adcp/types/generated.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
import re
from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic import ConfigDict, Field, field_validator

from adcp.types.base import AdCPBaseModel as BaseModel



Expand Down Expand Up @@ -945,6 +947,7 @@ class TasksListResponse(BaseModel):
# The simple code generator produces type aliases (e.g., PreviewCreativeRequest = Any)
# for complex schemas that use oneOf. We override them here with proper Pydantic classes
# to maintain type safety and enable batch API support.
# Note: All classes inherit from BaseModel (which is aliased to AdCPBaseModel for exclude_none).


class FormatId(BaseModel):
Expand Down