Skip to content

Instantly share code, notes, and snippets.

@wrouesnel
Created December 6, 2021 03:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrouesnel/74df5ce0622fbc7addcee5f6be82ed7f to your computer and use it in GitHub Desktop.
Save wrouesnel/74df5ce0622fbc7addcee5f6be82ed7f to your computer and use it in GitHub Desktop.
dataclass-and-union.py
from dataclasses import dataclass, field
from typing import List, Optional, ClassVar, Type, Union
import marshmallow_dataclass
import marshmallow_union
from marshmallow import fields
from marshmallow.validate import Equal
from marshmallow_polyfield import PolyField
from marshmallow_toplevel import TopLevelSchema
@dataclass
class A:
object_type: str = field(metadata={"validate": Equal("class_a")})
field_x: str
@dataclass
class B:
object_type: str = field(metadata={"validate": Equal("class_b")})
field_x: Optional[str]
field_y: str
@dataclass
class C:
object_type: str = field(metadata={"validate": Equal("class_c")})
field_z: str
ASchema = marshmallow_dataclass.class_schema(A)
BSchema = marshmallow_dataclass.class_schema(B)
CSchema = marshmallow_dataclass.class_schema(C)
class SourceStreamSchema(TopLevelSchema):
_toplevel = marshmallow.fields.List(
marshmallow_union.Union([
fields.Nested(ASchema),
fields.Nested(BSchema),
fields.Nested(CSchema),
])
)
source_stream = [
{
"object_type": "class_a",
"field_x": "value_x",
},
{
"object_type": "class_b",
"field_x": "value_bx",
"field_y": "value_by",
},
{
"object_type": "class_c",
"field_z": "value_z",
},
{
"object_type": "class_b",
"field_y": "value_by",
},
]
output = SourceStreamSchema().load(source_stream)
output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment