marshmallow-dataclass
marshmallow-dataclass is a Python library that enables the seamless conversion of standard Python dataclasses into Marshmallow schemas. This simplifies data serialization, deserialization, and validation by automatically generating schemas based on dataclass definitions. As of version 8.7.1, it provides robust type hint support and integrates well with existing Marshmallow workflows. Releases are generally driven by new features, bug fixes, or compatibility updates with Marshmallow.
Warnings
- breaking Version 8.0.0 removed `union_field` and moved `dataclass_json`. It also bumped the minimum Python version requirement to 3.8+.
- breaking Version 6.0.0 changed the signature of the `class_schema` function and discouraged the older `NewType` pattern for schema generation.
- gotcha Marshmallow `post_load` and `pre_load` methods must be defined on the *generated Marshmallow Schema*, not directly within the dataclass.
- gotcha Dataclass `Optional` types (`Optional[str]`) automatically map to Marshmallow fields with `allow_none=True`. If `None` is not desired for an optional field, you must explicitly set `allow_none=False` via metadata.
Install
-
pip install marshmallow-dataclass
Imports
- class_schema
from marshmallow_dataclass import class_schema
- dataclass_json
from marshmallow_dataclass.decorators import dataclass_json
Quickstart
from dataclasses import dataclass, field
from datetime import datetime
from marshmallow_dataclass import class_schema
@dataclass
class User:
id: int = field(metadata={'required': True})
name: str
email: str = field(metadata={'load_only': True})
created_at: datetime = field(default_factory=datetime.now, metadata={'dump_only': True})
# Generate a Marshmallow schema from the dataclass
UserSchema = class_schema(User)
# Instantiate the schema
user_schema = UserSchema()
# Example data
user_data = {
'id': 1,
'name': 'Alice',
'email': 'alice@example.com'
}
# Deserialize (load) data into a dataclass instance
try:
user_obj = user_schema.load(user_data)
print(f"Loaded User: {user_obj.name} (ID: {user_obj.id})")
# 'email' is load_only, so not in user_obj after load by default if not passed in constructor
print(f"User email (load_only): {user_data.get('email')}")
except Exception as e:
print(f"Error loading data: {e}")
# Serialize (dump) a dataclass instance to a dictionary
dumped_data = user_schema.dump(user_obj)
print(f"Dumped data: {dumped_data}")
# 'email' is load_only, 'created_at' is dump_only
assert 'email' not in dumped_data
assert 'created_at' in dumped_data
assert dumped_data['id'] == 1