single |
# *cattrs*: Flexible Object Serialization and Validation
*Because validation belongs to the edges.*
[Documentation]
[![License: MIT]](https://github.com/hynek/stamina/blob/main/LICENSE)
[PyPI]
[Supported Python Versions]
[Downloads]
[Coverage]
---
**cattrs** is a Swiss Army knife for (un)structuring and validating data in
Python.
In practice, that means it converts **unstructured dictionaries** into
**proper classes** and back, while **validating** their contents.
## Example
_cattrs_ works best with [_attrs_] classes, and [dataclasses] where simple
(un-)structuring works out of the box, even for nested data, without
polluting your data model with serialization details:
```python
>>> from attrs import define
>>> from cattrs import structure, unstructure
>>> @define
... class C:
... a: int
... b: list[str]
>>> instance = structure({'a': 1, 'b': ['x', 'y']}, C)
>>> instance
C(a=1, b=['x', 'y'])
>>> unstructure(instance)
{'a': 1, 'b': ['x', 'y']}
```
Have a look at [*Why *cattrs*?*] for more examples!
## Features
### Recursive Unstructuring
- _attrs_ classes and dataclasses are converted into dictionaries in a way
similar to `attrs.asdict()`, or into tuples in a way similar to
`attrs.astuple()`.
- Enumeration instances are converted to their values.
- Other types are let through without conversion. This includes types such
as integers, dictionaries, lists and instances of non-_attrs_ classes.
- Custom converters for any type can be registered using
`register_unstructure_hook`.
### Recursive Structuring
Converts unstructured data into structured data, recursively, according to
your specification given as a type.
The following types are supported:
- `typing.Optional[T]` and its 3.10+ form, `T | None`.
- `list[T]`, `typing.List[T]`, `typing.MutableSequence[T]`,
`typing.Sequence[T]` convert to a lists.
- `tuple` and `typing.Tuple` (both variants, `tuple[T, ...]` and `tuple[X,
Y, Z]`).
- `set[T]`, `typing.MutableSet[T]`, and `typing.Set[T]` convert to a sets.
- `frozenset[T]`, and `typing.FrozenSet[T]` convert to a frozensets.
- `dict[K, V]`, `typing.Dict[K, V]`, `typing.MutableMapping[K, V]`, and
`typing.Mapping[K, V]` convert to a dictionaries.
- [`typing.TypedDict`], ordinary and generic.
- [`typing.NewType`]
- [PEP 695 type aliases] on 3.12+
- _attrs_ classes with simple attributes and the usual `__init__`[^simple].
- All _attrs_ classes and dataclasses with the usual `__init__`, if their
complex attributes have type metadata.
- Unions of supported _attrs_ classes, given that all of the classes have a
unique field.
- Unions of anything, if you provide a disambiguation function for it.
- Custom converters for any type can be registered using
`register_structure_hook`.
[^simple]: Simple attributes are attributes that can be assigned
unstructured data, like numbers, strings, and collections of unstructured
data.
### Batteries Included
_cattrs_ comes with pre-configured converters for a number of serialization
libraries, including JSON (standard library, [_orjson_], [UltraJSON]),
[_msgpack_], [_cbor2_], [_bson_], [PyYAML], [_tomlkit_] and [_msgspec_]
|