Skip to content

Model Engines

Engine support is exposed through saffier.engines and mirrored from the top-level saffier package for convenience.

Use this reference together with the practical guide in Model Engines.

Registration helpers

saffier.register_model_engine

register_model_engine(name, engine, *, overwrite=False)

Register one model-engine adapter in the global registry.

Source code in saffier/engines/base.py
308
309
310
311
312
313
314
315
def register_model_engine(
    name: str | None,
    engine: ModelEngineFactory,
    *,
    overwrite: bool = False,
) -> ModelEngine:
    """Register one model-engine adapter in the global registry."""
    return _MODEL_ENGINE_REGISTRY.register(name, engine, overwrite=overwrite)

saffier.get_model_engine

get_model_engine(name)

Return one globally registered model-engine adapter.

Source code in saffier/engines/base.py
318
319
320
def get_model_engine(name: str) -> ModelEngine:
    """Return one globally registered model-engine adapter."""
    return _MODEL_ENGINE_REGISTRY.get(name)

Base adapter

saffier.ModelEngine

Bases: ABC

Base class for optional model-engine adapters layered on top of Saffier.

Concrete adapters expose external model representations such as Pydantic or msgspec while keeping Saffier's own model lifecycle as the source of truth.

name class-attribute instance-attribute

name = ''

build_projection_payload

build_projection_payload(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Build the Saffier-owned payload used to project one instance.

PARAMETER DESCRIPTION
instance

Source Saffier model instance.

TYPE: Model

include

Optional nested include rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude

Optional nested exclude rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude_none

Whether None values should be omitted.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
dict[str, Any]

dict[str, Any]: Payload containing Saffier field data plus any

dict[str, Any]

declared plain Python fields.

Source code in saffier/engines/base.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def build_projection_payload(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Build the Saffier-owned payload used to project one instance.

    Args:
        instance: Source Saffier model instance.
        include: Optional nested include rules.
        exclude: Optional nested exclude rules.
        exclude_none: Whether `None` values should be omitted.

    Returns:
        dict[str, Any]: Payload containing Saffier field data plus any
        declared plain Python fields.
    """
    payload = instance.model_dump(include=include, exclude=exclude, exclude_none=exclude_none)

    for field_name in type(instance).get_plain_model_fields():
        if not self._is_included(field_name, include) or self._is_excluded(
            field_name, exclude
        ):
            continue
        if field_name not in instance.__dict__:
            continue
        value = instance.__dict__[field_name]
        if exclude_none and value is None:
            continue
        payload[field_name] = value
    return payload

project_model

project_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Project one Saffier model instance into the engine representation.

Source code in saffier/engines/base.py
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def project_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> Any:
    """Project one Saffier model instance into the engine representation."""
    payload = self.build_projection_payload(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    return self.validate_model(type(instance), payload, mode="projection")

dump_model

dump_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected engine model back into a plain dictionary.

Source code in saffier/engines/base.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def dump_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Serialize one projected engine model back into a plain dictionary."""
    projected = self.project_model(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    if isinstance(projected, Mapping):
        return dict(projected)

    dump = getattr(projected, "model_dump", None)
    if callable(dump):
        kwargs: dict[str, Any] = {"exclude_unset": True, "exclude_none": exclude_none}
        if include is not None:
            kwargs["include"] = include
        if exclude is not None:
            kwargs["exclude"] = exclude
        try:
            return cast("dict[str, Any]", dump(**kwargs))
        except TypeError:
            kwargs.pop("exclude_unset", None)
            return cast("dict[str, Any]", dump(**kwargs))

    if hasattr(projected, "__dict__"):
        payload = {
            key: value
            for key, value in projected.__dict__.items()
            if not key.startswith("_")
            and self._is_included(key, include)
            and not self._is_excluded(key, exclude)
        }
        if exclude_none:
            payload = {key: value for key, value in payload.items() if value is not None}
        return payload

    raise TypeError(
        f"Engine '{self.name}' returned '{type(projected).__name__}' without a dump interface."
    )

dump_model_json

dump_model_json(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected engine model into JSON.

Source code in saffier/engines/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def dump_model_json(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> str:
    """Serialize one projected engine model into JSON."""
    projected = self.project_model(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    dump_json = getattr(projected, "model_dump_json", None)
    if callable(dump_json):
        kwargs: dict[str, Any] = {"exclude_unset": True, "exclude_none": exclude_none}
        if include is not None:
            kwargs["include"] = include
        if exclude is not None:
            kwargs["exclude"] = exclude
        try:
            return cast("str", dump_json(**kwargs))
        except TypeError:
            kwargs.pop("exclude_unset", None)
            return cast("str", dump_json(**kwargs))

    return orjson.dumps(
        self.dump_model(
            instance,
            include=include,
            exclude=exclude,
            exclude_none=exclude_none,
        ),
        option=orjson.OPT_NON_STR_KEYS,
    ).decode("utf-8")

get_model_class abstractmethod

get_model_class(model_class, *, mode='projection')

Return the engine-backed representation class for one Saffier model.

Source code in saffier/engines/base.py
184
185
186
@abstractmethod
def get_model_class(self, model_class: type[Model], *, mode: str = "projection") -> type[Any]:
    """Return the engine-backed representation class for one Saffier model."""

validate_model abstractmethod

validate_model(model_class, value, *, mode='validation')

Validate or coerce value into the engine-backed representation.

Source code in saffier/engines/base.py
188
189
190
191
192
193
194
195
196
@abstractmethod
def validate_model(
    self,
    model_class: type[Model],
    value: Any,
    *,
    mode: str = "validation",
) -> Any:
    """Validate or coerce `value` into the engine-backed representation."""

to_saffier_data abstractmethod

to_saffier_data(model_class, value, *, exclude_unset=False)

Convert an engine-backed value back into Saffier constructor data.

Source code in saffier/engines/base.py
198
199
200
201
202
203
204
205
206
@abstractmethod
def to_saffier_data(
    self,
    model_class: type[Model],
    value: Any,
    *,
    exclude_unset: bool = False,
) -> dict[str, Any]:
    """Convert an engine-backed value back into Saffier constructor data."""

json_schema abstractmethod

json_schema(model_class, *, mode='projection', **kwargs)

Return an engine-generated schema for the Saffier model.

Source code in saffier/engines/base.py
208
209
210
211
212
213
214
215
216
@abstractmethod
def json_schema(
    self,
    model_class: type[Model],
    *,
    mode: str = "projection",
    **kwargs: Any,
) -> dict[str, Any]:
    """Return an engine-generated schema for the Saffier model."""

Built-in adapters

saffier.PydanticModelEngine

PydanticModelEngine(*, config=None)

Bases: ModelEngine

Pydantic-backed adapter that projects validated Saffier model payloads.

Initialize the adapter with optional ConfigDict overrides.

Source code in saffier/engines/pydantic.py
21
22
23
24
def __init__(self, *, config: dict[str, Any] | None = None) -> None:
    """Initialize the adapter with optional `ConfigDict` overrides."""
    self.config = dict(config or {})
    self._model_cache: dict[tuple[type[Model], str, int], type[Any]] = {}

name class-attribute instance-attribute

name = 'pydantic'

config instance-attribute

config = dict(config or {})

build_projection_payload

build_projection_payload(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Build the Saffier-owned payload used to project one instance.

PARAMETER DESCRIPTION
instance

Source Saffier model instance.

TYPE: Model

include

Optional nested include rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude

Optional nested exclude rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude_none

Whether None values should be omitted.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
dict[str, Any]

dict[str, Any]: Payload containing Saffier field data plus any

dict[str, Any]

declared plain Python fields.

Source code in saffier/engines/base.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def build_projection_payload(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Build the Saffier-owned payload used to project one instance.

    Args:
        instance: Source Saffier model instance.
        include: Optional nested include rules.
        exclude: Optional nested exclude rules.
        exclude_none: Whether `None` values should be omitted.

    Returns:
        dict[str, Any]: Payload containing Saffier field data plus any
        declared plain Python fields.
    """
    payload = instance.model_dump(include=include, exclude=exclude, exclude_none=exclude_none)

    for field_name in type(instance).get_plain_model_fields():
        if not self._is_included(field_name, include) or self._is_excluded(
            field_name, exclude
        ):
            continue
        if field_name not in instance.__dict__:
            continue
        value = instance.__dict__[field_name]
        if exclude_none and value is None:
            continue
        payload[field_name] = value
    return payload

project_model

project_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Project one Saffier model instance into the engine representation.

Source code in saffier/engines/base.py
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def project_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> Any:
    """Project one Saffier model instance into the engine representation."""
    payload = self.build_projection_payload(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    return self.validate_model(type(instance), payload, mode="projection")

dump_model

dump_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected engine model back into a plain dictionary.

Source code in saffier/engines/base.py
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def dump_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Serialize one projected engine model back into a plain dictionary."""
    projected = self.project_model(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    if isinstance(projected, Mapping):
        return dict(projected)

    dump = getattr(projected, "model_dump", None)
    if callable(dump):
        kwargs: dict[str, Any] = {"exclude_unset": True, "exclude_none": exclude_none}
        if include is not None:
            kwargs["include"] = include
        if exclude is not None:
            kwargs["exclude"] = exclude
        try:
            return cast("dict[str, Any]", dump(**kwargs))
        except TypeError:
            kwargs.pop("exclude_unset", None)
            return cast("dict[str, Any]", dump(**kwargs))

    if hasattr(projected, "__dict__"):
        payload = {
            key: value
            for key, value in projected.__dict__.items()
            if not key.startswith("_")
            and self._is_included(key, include)
            and not self._is_excluded(key, exclude)
        }
        if exclude_none:
            payload = {key: value for key, value in payload.items() if value is not None}
        return payload

    raise TypeError(
        f"Engine '{self.name}' returned '{type(projected).__name__}' without a dump interface."
    )

dump_model_json

dump_model_json(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected engine model into JSON.

Source code in saffier/engines/base.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
def dump_model_json(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> str:
    """Serialize one projected engine model into JSON."""
    projected = self.project_model(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    dump_json = getattr(projected, "model_dump_json", None)
    if callable(dump_json):
        kwargs: dict[str, Any] = {"exclude_unset": True, "exclude_none": exclude_none}
        if include is not None:
            kwargs["include"] = include
        if exclude is not None:
            kwargs["exclude"] = exclude
        try:
            return cast("str", dump_json(**kwargs))
        except TypeError:
            kwargs.pop("exclude_unset", None)
            return cast("str", dump_json(**kwargs))

    return orjson.dumps(
        self.dump_model(
            instance,
            include=include,
            exclude=exclude,
            exclude_none=exclude_none,
        ),
        option=orjson.OPT_NON_STR_KEYS,
    ).decode("utf-8")

get_model_class

get_model_class(model_class, *, mode='projection')

Return the Pydantic model class for one Saffier model.

Source code in saffier/engines/pydantic.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def get_model_class(self, model_class: type[Model], *, mode: str = "projection") -> type[Any]:
    """Return the Pydantic model class for one Saffier model."""
    _, config_dict, _, create_model = self._import_pydantic()
    cache_key = (model_class, mode, getattr(model_class.meta, "_engine_generation", 0))
    if cache_key in self._model_cache:
        return self._model_cache[cache_key]

    fields: dict[str, tuple[Any, Any]] = {}
    for field_name, field in model_class.fields.items():
        if field.__class__.__name__ == "ManyToManyField":
            continue
        if mode == "projection" and getattr(field, "exclude", False):
            continue
        fields[field_name] = self._field_definition(
            field_name,
            field,
            model_class,
            mode=mode,
        )

    for field_name, plain_field in model_class.get_plain_model_fields().items():
        fields[field_name] = self._plain_field_definition(
            field_name,
            plain_field,
            model_class,
            mode=mode,
        )

    config = config_dict(
        arbitrary_types_allowed=True,
        extra="forbid",
        from_attributes=True,
        populate_by_name=True,
        validate_assignment=(mode == "validation"),
        **self.config,
    )
    engine_model = create_model(
        f"{model_class.__name__}{mode.capitalize()}EngineModel",
        __config__=config,
        __module__=model_class.__module__,
        **fields,
    )
    self._model_cache[cache_key] = engine_model
    return engine_model

validate_model

validate_model(model_class, value, *, mode='validation')

Validate or coerce a value into the Pydantic representation.

Source code in saffier/engines/pydantic.py
130
131
132
133
134
135
136
137
138
139
140
141
142
143
def validate_model(
    self,
    model_class: type[Model],
    value: Any,
    *,
    mode: str = "validation",
) -> Any:
    """Validate or coerce a value into the Pydantic representation."""
    engine_model = self.get_model_class(model_class, mode=mode)
    if isinstance(value, engine_model):
        return value
    if hasattr(value, "__db_model__"):
        value = self.build_projection_payload(cast("Model", value))
    return engine_model.model_validate(value)

to_saffier_data

to_saffier_data(model_class, value, *, exclude_unset=False)

Convert a Pydantic value back into a Saffier constructor payload.

Source code in saffier/engines/pydantic.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
def to_saffier_data(
    self,
    model_class: type[Model],
    value: Any,
    *,
    exclude_unset: bool = False,
) -> dict[str, Any]:
    """Convert a Pydantic value back into a Saffier constructor payload."""
    if hasattr(value, "model_dump"):
        kwargs = {"exclude_unset": exclude_unset}
        try:
            return cast("dict[str, Any]", value.model_dump(**kwargs))
        except TypeError:
            return cast("dict[str, Any]", value.model_dump())
    validated = self.validate_model(model_class, value, mode="validation")
    return cast("dict[str, Any]", validated.model_dump(exclude_unset=exclude_unset))

json_schema

json_schema(model_class, *, mode='projection', **kwargs)

Return the Pydantic-generated JSON schema for one model.

Source code in saffier/engines/pydantic.py
162
163
164
165
166
167
168
169
170
171
def json_schema(
    self,
    model_class: type[Model],
    *,
    mode: str = "projection",
    **kwargs: Any,
) -> dict[str, Any]:
    """Return the Pydantic-generated JSON schema for one model."""
    engine_model = self.get_model_class(model_class, mode=mode)
    return cast("dict[str, Any]", engine_model.model_json_schema(**kwargs))

saffier.MsgspecModelEngine

MsgspecModelEngine(*, strict=False, struct_config=None)

Bases: ModelEngine

msgspec-backed adapter that projects Saffier models into Struct types.

The adapter keeps Saffier in charge of persistence and queryset behavior while using msgspec for typed validation, JSON schema generation, and serialization.

Initialize the adapter.

PARAMETER DESCRIPTION
strict

Whether validation should use msgspec strict conversion rules.

TYPE: bool DEFAULT: False

struct_config

Extra keyword arguments forwarded to msgspec.defstruct().

TYPE: dict[str, Any] | None DEFAULT: None

Source code in saffier/engines/msgspec.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def __init__(
    self,
    *,
    strict: bool = False,
    struct_config: dict[str, Any] | None = None,
) -> None:
    """Initialize the adapter.

    Args:
        strict: Whether validation should use msgspec strict conversion
            rules.
        struct_config: Extra keyword arguments forwarded to
            `msgspec.defstruct()`.
    """
    self.strict = strict
    self.struct_config = dict(struct_config or {})
    self._model_cache: dict[tuple[type[Model], str, int], type[Any]] = {}

name class-attribute instance-attribute

name = 'msgspec'

strict instance-attribute

strict = strict

struct_config instance-attribute

struct_config = dict(struct_config or {})

build_projection_payload

build_projection_payload(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Build the Saffier-owned payload used to project one instance.

PARAMETER DESCRIPTION
instance

Source Saffier model instance.

TYPE: Model

include

Optional nested include rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude

Optional nested exclude rules.

TYPE: EngineIncludeExclude DEFAULT: None

exclude_none

Whether None values should be omitted.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
dict[str, Any]

dict[str, Any]: Payload containing Saffier field data plus any

dict[str, Any]

declared plain Python fields.

Source code in saffier/engines/base.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
def build_projection_payload(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Build the Saffier-owned payload used to project one instance.

    Args:
        instance: Source Saffier model instance.
        include: Optional nested include rules.
        exclude: Optional nested exclude rules.
        exclude_none: Whether `None` values should be omitted.

    Returns:
        dict[str, Any]: Payload containing Saffier field data plus any
        declared plain Python fields.
    """
    payload = instance.model_dump(include=include, exclude=exclude, exclude_none=exclude_none)

    for field_name in type(instance).get_plain_model_fields():
        if not self._is_included(field_name, include) or self._is_excluded(
            field_name, exclude
        ):
            continue
        if field_name not in instance.__dict__:
            continue
        value = instance.__dict__[field_name]
        if exclude_none and value is None:
            continue
        payload[field_name] = value
    return payload

project_model

project_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Project one Saffier model instance into the engine representation.

Source code in saffier/engines/base.py
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
def project_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> Any:
    """Project one Saffier model instance into the engine representation."""
    payload = self.build_projection_payload(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    return self.validate_model(type(instance), payload, mode="projection")

get_model_class

get_model_class(model_class, *, mode='projection')

Return the msgspec struct type for one Saffier model.

Source code in saffier/engines/msgspec.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
def get_model_class(self, model_class: type[Model], *, mode: str = "projection") -> type[Any]:
    """Return the msgspec struct type for one Saffier model."""
    msgspec = self._import_msgspec()
    cache_key = (model_class, mode, getattr(model_class.meta, "_engine_generation", 0))
    if cache_key in self._model_cache:
        return self._model_cache[cache_key]

    fields: list[tuple[Any, ...]] = []
    for field_name, field in model_class.fields.items():
        if field.__class__.__name__ == "ManyToManyField":
            continue
        if mode == "projection" and getattr(field, "exclude", False):
            continue
        fields.append(self._field_definition(field_name, field, model_class, mode=mode))

    for field_name, plain_field in model_class.get_plain_model_fields().items():
        fields.append(
            self._plain_field_definition(field_name, plain_field, model_class, mode=mode)
        )

    namespace = {
        "__doc__": (
            f"msgspec {mode} model generated for the Saffier model '{model_class.__name__}'."
        )
    }
    engine_model = msgspec.defstruct(
        f"{model_class.__name__}{mode.capitalize()}EngineModel",
        fields,
        bases=(msgspec.Struct,),
        module=model_class.__module__,
        namespace=namespace,
        omit_defaults=True,
        forbid_unknown_fields=(mode == "validation"),
        kw_only=True,
        **self.struct_config,
    )
    self._model_cache[cache_key] = engine_model
    return engine_model

validate_model

validate_model(model_class, value, *, mode='validation')

Validate or coerce a value into the msgspec struct representation.

Source code in saffier/engines/msgspec.py
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def validate_model(
    self,
    model_class: type[Model],
    value: Any,
    *,
    mode: str = "validation",
) -> Any:
    """Validate or coerce a value into the msgspec struct representation."""
    msgspec = self._import_msgspec()
    engine_model = self.get_model_class(model_class, mode=mode)
    if isinstance(value, engine_model):
        return value
    if hasattr(value, "__db_model__"):
        value = self.build_projection_payload(cast("Model", value))
    return msgspec.convert(
        value,
        type=engine_model,
        strict=self.strict if mode == "validation" else False,
        from_attributes=True,
        str_keys=True,
    )

to_saffier_data

to_saffier_data(model_class, value, *, exclude_unset=False)

Convert a msgspec value back into a Saffier constructor payload.

Source code in saffier/engines/msgspec.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def to_saffier_data(
    self,
    model_class: type[Model],
    value: Any,
    *,
    exclude_unset: bool = False,
) -> dict[str, Any]:
    """Convert a msgspec value back into a Saffier constructor payload."""
    validated = self.validate_model(model_class, value, mode="validation")
    if exclude_unset and isinstance(value, Mapping):
        return self._struct_to_data(validated, only_fields=set(value.keys()))
    if exclude_unset:
        msgspec = self._import_msgspec()
        return cast("dict[str, Any]", msgspec.to_builtins(validated))
    return self._struct_to_data(validated)

dump_model

dump_model(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected msgspec model back into a dictionary.

Source code in saffier/engines/msgspec.py
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
def dump_model(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> dict[str, Any]:
    """Serialize one projected msgspec model back into a dictionary."""
    projection_payload = self.build_projection_payload(
        instance,
        include=include,
        exclude=exclude,
        exclude_none=exclude_none,
    )
    projected = self.validate_model(type(instance), projection_payload, mode="projection")
    return self._struct_to_data(
        projected,
        only_fields=set(projection_payload.keys()),
        exclude_none=exclude_none,
    )

dump_model_json

dump_model_json(
    instance,
    *,
    include=None,
    exclude=None,
    exclude_none=False,
)

Serialize one projected msgspec model into JSON.

Source code in saffier/engines/msgspec.py
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
def dump_model_json(
    self,
    instance: Model,
    *,
    include: EngineIncludeExclude = None,
    exclude: EngineIncludeExclude = None,
    exclude_none: bool = False,
) -> str:
    """Serialize one projected msgspec model into JSON."""
    msgspec = self._import_msgspec()
    return cast(
        "bytes",
        msgspec.json.encode(
            self.dump_model(
                instance,
                include=include,
                exclude=exclude,
                exclude_none=exclude_none,
            )
        ),
    ).decode("utf-8")

json_schema

json_schema(model_class, *, mode='projection', **kwargs)

Return the msgspec-generated JSON schema for one model.

Source code in saffier/engines/msgspec.py
265
266
267
268
269
270
271
272
273
274
275
276
277
def json_schema(
    self,
    model_class: type[Model],
    *,
    mode: str = "projection",
    **kwargs: Any,
) -> dict[str, Any]:
    """Return the msgspec-generated JSON schema for one model."""
    del kwargs
    msgspec = self._import_msgspec()
    return cast(
        "dict[str, Any]", msgspec.json.schema(self.get_model_class(model_class, mode=mode))
    )