Handle Mixed-Type JSON Fields with Python Union Types
Learn how to convert JSON fields that contain different types across responses into Python Union types. Covers Union[X, Y], X | Y syntax, and type narrowing.
Detailed Explanation
Union Types for Mixed JSON Fields
Some JSON APIs return fields that can be different types depending on context — a field might be a string in one response and an object in another. Python handles this with Union.
Example JSON (string result)
{
"type": "simple",
"result": "success"
}
Example JSON (object result)
{
"type": "detailed",
"result": {
"status": "success",
"count": 42
}
}
Generated Python
from dataclasses import dataclass
from typing import Union
@dataclass
class DetailedResult:
status: str
count: int
@dataclass
class Response:
type: str
result: Union[str, DetailedResult]
Python 3.10+ Syntax
@dataclass
class Response:
type: str
result: str | DetailedResult
Type Narrowing
Use isinstance() to narrow the union at runtime:
if isinstance(response.result, str):
print(response.result.upper()) # mypy knows it's str
elif isinstance(response.result, DetailedResult):
print(response.result.count) # mypy knows it's DetailedResult
Discriminated Unions with Literal
For cleaner narrowing, use a discriminant field:
from typing import Literal
@dataclass
class SimpleResponse:
type: Literal["simple"]
result: str
@dataclass
class DetailedResponse:
type: Literal["detailed"]
result: DetailedResult
Response = SimpleResponse | DetailedResponse
With Pydantic
Pydantic v2 supports discriminated unions natively:
from pydantic import BaseModel, Discriminator, Tag
from typing import Annotated, Union
class SimpleResponse(BaseModel):
type: Literal["simple"]
result: str
class DetailedResponse(BaseModel):
type: Literal["detailed"]
result: DetailedResult
Response = Annotated[
Union[SimpleResponse, DetailedResponse],
Discriminator("type"),
]
When to Use Unions
- Polymorphic API responses — Different shapes based on a type or status field.
- Webhook payloads — Event type determines the payload structure.
- Flexible input — Accept multiple formats for the same field.
Use Case
You are consuming a webhook API where the payload structure varies by event type, and you need Python types that allow mypy to verify you handle every variant correctly.
Try It — JSON to Python Converter
Related Topics
Convert JSON String Values to Python Enums
Advanced Patterns
Handle Optional and Nullable JSON Fields in Python
Type Annotations
Convert JSON to a Pydantic BaseModel in Python
Pydantic & TypedDict
Convert REST API Response JSON to Python Classes
Advanced Patterns
Convert Simple JSON to a Python Dataclass
Dataclasses