Dacite

raw JSON →
1.9.2 verified Tue May 12 auth: no python install: verified

Dacite is a Python library that simplifies the creation of data class instances from dictionaries. It focuses on converting raw dictionary data (e.g., from HTTP requests or databases) into robust, type-hinted dataclass objects, leveraging PEP 557 dataclasses. The library is actively maintained, with version 1.9.2 released recently, and receives regular updates including performance improvements and new feature support like generics, forward references, and unions.

pip install dacite
error dacite.exceptions.WrongTypeError: wrong value type for field "<field_name>" - should be "<expected_type>" instead of value "<value>" of type "<actual_type>"
cause The type of the input value in the dictionary does not match the expected type hint defined in the dataclass field, and dacite's default behavior does not perform automatic casting.
fix
Ensure the input data types precisely match the dataclass type hints, or enable casting for specific types using dacite.Config(cast=[<TypeToCast>]) or provide a type_hook for complex conversions. For example, to allow integers for a float field, use Union[int, float] or configure casting for floats.
error dacite.exceptions.MissingValueError: missing value for field "<field_name>"
cause A required field in the dataclass (one without a default value or `Optional` annotation) is not present in the input dictionary provided to `from_dict`.
fix
Ensure all required fields are present in the input dictionary, or make the dataclass field optional using typing.Optional[<Type>] (e.g., Optional[str]) or by providing a default value (e.g., field: str = 'default').
error dacite.exceptions.UnionMatchError: can not match type "<actual_type>" to any type of "<field_name>" union: <Union[Type1, Type2]>
cause The input value for a field annotated with `typing.Union` does not successfully match any of the types specified within that union.
fix
Verify that the input data conforms to one of the types in the Union. For complex union types, ensure nested structures or values correctly align with one of the union's member types. Sometimes, adjusting the order of types in Union or providing specific type_hooks can help resolve ambiguities.
error dacite.exceptions.UnexpectedDataError: unexpected keys in input data: <key1>, <key2>
cause The `dacite.Config` was set with `strict=True`, but the input dictionary contains keys that are not defined as fields in the target dataclass.
fix
Either remove the extraneous keys from the input dictionary, or set strict=False in the dacite.Config to allow dacite to ignore unexpected keys: from_dict(MyDataClass, data, config=Config(strict=False)).
gotcha Dacite is a data-to-object mapping library, not a data validation library. It primarily focuses on converting dictionaries to dataclass instances based on type hints. For robust data validation, it's recommended to combine Dacite with a dedicated validation library.
fix Integrate with a data validation library (e.g., Pydantic, Marshmallow) before passing data to `dacite.from_dict` if validation is required.
gotcha By default, Dacite expects all non-optional fields in the target dataclass to have corresponding keys in the input dictionary. If a required field is missing from the input dictionary and does not have a default value in the dataclass, a `MissingValueError` will be raised.
fix Ensure all required dictionary keys are present, or provide default values for optional fields in your dataclass definitions.
gotcha Dacite performs basic type checking but does not automatically coerce types by default (e.g., converting a string '123' to an integer 123 for an `int` field), which can lead to `WrongTypeError`. Automatic casting needs to be explicitly enabled.
fix Use `Config(cast=[YourType])` to enable casting for specific types, or `Config(type_hooks={YourType: lambda v: YourType(v)})` for custom transformations. Note that `cast` works for base types and their subtypes.
gotcha When using `typing.Union`, Dacite by default tries to find the first matching type. If `Config(strict_unions_match=True)` is used, it will raise a `StrictUnionMatchError` if more than one type in the Union could match the input data.
fix Carefully define `Union` types to avoid ambiguity or handle `StrictUnionMatchError` if `strict_unions_match` is enabled. Consider the order of types in the Union if multiple types could potentially match the input data without `strict_unions_match`.
gotcha Dacite does not dynamically add fields to dataclasses that are not predefined in the dataclass definition. If your input dictionary contains keys not present in the dataclass, those keys will be ignored during conversion unless `Config(check_types=False)` is used (which is not recommended for type safety).
fix Ensure your dataclass definition accurately reflects all fields you intend to deserialize. If you have genuinely dynamic keys, consider using `dict` types within your dataclass for those sections.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.03s 17.9M
3.10 alpine (musl) - - 0.03s 17.9M
3.10 slim (glibc) wheel 1.5s 0.02s 18M
3.10 slim (glibc) - - 0.02s 18M
3.11 alpine (musl) wheel - 0.06s 19.7M
3.11 alpine (musl) - - 0.07s 19.7M
3.11 slim (glibc) wheel 1.6s 0.05s 20M
3.11 slim (glibc) - - 0.05s 20M
3.12 alpine (musl) wheel - 0.05s 11.6M
3.12 alpine (musl) - - 0.06s 11.6M
3.12 slim (glibc) wheel 1.5s 0.05s 12M
3.12 slim (glibc) - - 0.06s 12M
3.13 alpine (musl) wheel - 0.05s 11.4M
3.13 alpine (musl) - - 0.06s 11.2M
3.13 slim (glibc) wheel 1.5s 0.05s 12M
3.13 slim (glibc) - - 0.05s 12M
3.9 alpine (musl) wheel - 0.03s 17.4M
3.9 alpine (musl) - - 0.03s 17.4M
3.9 slim (glibc) wheel 1.7s 0.02s 18M
3.9 slim (glibc) - - 0.03s 18M

This quickstart demonstrates how to convert a dictionary into a nested dataclass structure using `from_dict`. It also shows how to use the `Config` object to apply custom type hooks for transformation during the conversion process.

from dataclasses import dataclass
from dacite import from_dict, Config

@dataclass
class User:
    name: str
    age: int
    is_active: bool

@dataclass
class Address:
    street: str
    city: str

@dataclass
class Profile:
    user: User
    address: Address
    preferences: dict

data = {
    'user': {'name': 'Jane Doe', 'age': 28, 'is_active': False},
    'address': {'street': '123 Main St', 'city': 'Anytown'},
    'preferences': {'theme': 'dark', 'notifications': True}
}

# Basic conversion
profile = from_dict(data_class=Profile, data=data)
print(profile)
# Expected: Profile(user=User(name='Jane Doe', age=28, is_active=False), address=Address(street='123 Main St', city='Anytown'), preferences={'theme': 'dark', 'notifications': True})

# Example with a type hook (e.g., converting all strings to uppercase)
@dataclass
class Item:
    id: str
    value: int

def uppercase_str(s: str) -> str:
    return s.upper()

item_data = {'id': 'item-abc', 'value': 100}
config_with_hook = Config(type_hooks={str: uppercase_str})
item = from_dict(data_class=Item, data=item_data, config=config_with_hook)
print(item)
# Expected: Item(id='ITEM-ABC', value=100)