CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-dacite

Simple creation of data classes from dictionaries with advanced type support and validation

Pending
Overview
Eval results
Files

Dacite

Dacite simplifies the creation of Python data classes from dictionaries. It bridges the gap between raw dictionary data (from HTTP requests, databases, etc.) and strongly-typed data structures, enabling developers to create robust data transfer objects (DTOs) with minimal boilerplate code while maintaining type safety.

Package Information

  • Package Name: dacite
  • Package Type: pypi
  • Language: Python
  • Installation: pip install dacite
  • Minimum Python Version: 3.7

Core Imports

from dacite import from_dict, Config

For exceptions:

from dacite import (
    DaciteError,
    DaciteFieldError,
    WrongTypeError,
    MissingValueError,
    UnionMatchError,
    StrictUnionMatchError,
    ForwardReferenceError,
    UnexpectedDataError,
)

For cache management:

from dacite import set_cache_size, get_cache_size, clear_cache

Basic Usage

from dataclasses import dataclass
from dacite import from_dict

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

data = {
    'name': 'John',
    'age': 30,
    'is_active': True,
}

user = from_dict(data_class=User, data=data)
assert user == User(name='John', age=30, is_active=True)

Capabilities

Dictionary to Dataclass Conversion

The core functionality that converts dictionaries to dataclass instances with full type support and validation.

def from_dict(data_class: Type[T], data: Data, config: Optional[Config] = None) -> T:
    """
    Create a data class instance from a dictionary.

    Args:
        data_class: A data class type to create an instance of
        data: Dictionary-like data to convert (must support keys(), __getitem__, __contains__)
        config: Optional configuration for controlling the conversion process

    Returns:
        An instance of the specified data class

    Raises:
        DaciteError: Base exception for all dacite-related errors
        WrongTypeError: When a value has the wrong type for a field
        MissingValueError: When a required field is missing from the data
        UnionMatchError: When a value cannot match any union type
        StrictUnionMatchError: When multiple union types match in strict mode
        ForwardReferenceError: When forward references cannot be resolved
        UnexpectedDataError: When strict mode encounters unexpected fields
    """

Configuration

Control the conversion process with various options for type handling, validation, and data transformation.

@dataclass
class Config:
    """
    Configuration object for controlling from_dict behavior.
    
    Attributes:
        type_hooks: Dictionary mapping types to transformation functions
        cast: List of types to attempt casting values to
        forward_references: Dictionary for resolving forward references
        check_types: Enable/disable runtime type checking (default: True)
        strict: Enable strict mode to reject unexpected fields (default: False)
        strict_unions_match: Enable strict matching for union types (default: False)
        convert_key: Function to transform dictionary keys (default: identity function)
    """
    type_hooks: Dict[Type, Callable[[Any], Any]]
    cast: List[Type]
    forward_references: Optional[Dict[str, Any]]
    check_types: bool
    strict: bool
    strict_unions_match: bool
    convert_key: Callable[[str], str]

Usage example with configuration:

from dacite import from_dict, Config
from dataclasses import dataclass
from typing import Optional

@dataclass
class Person:
    name: str
    age: Optional[int]
    email: str

config = Config(
    type_hooks={str: str.strip},  # Strip whitespace from strings
    check_types=True,             # Enable type checking
    strict=True,                  # Reject unexpected fields
    convert_key=lambda key: key.lower()  # Convert keys to lowercase
)

data = {"NAME": "  John Doe  ", "AGE": None, "EMAIL": "john@example.com"}
person = from_dict(Person, data, config)

Cache Management

Control internal caching for performance optimization, particularly useful for applications with many dataclass conversions.

def set_cache_size(size: Optional[int]) -> None:
    """
    Set the maximum cache size for internal caching.
    
    Args:
        size: Maximum cache size (None for unlimited, 0 to disable caching)
    """

def get_cache_size() -> Optional[int]:
    """
    Get the current cache size setting.
    
    Returns:
        Current cache size (None if unlimited)
    """

def clear_cache() -> None:
    """
    Clear all internal caches.
    
    This can be useful for memory management or when type definitions change.
    """

Exception Handling

Comprehensive exception hierarchy for different error conditions during conversion.

class DaciteError(Exception):
    """Base exception class for all dacite-related errors."""

class DaciteFieldError(DaciteError):
    """
    Base class for field-specific errors.
    
    Attributes:
        field_path: Path to the problematic field (e.g., 'user.address.street')
    """
    field_path: Optional[str]
    
    def update_path(self, parent_field_path: str) -> None:
        """Update the field path with parent context."""

class WrongTypeError(DaciteFieldError):
    """
    Raised when a value has the wrong type for a field.
    
    Attributes:
        field_type: Expected field type
        value: Actual value that caused the error
    """
    field_type: Type
    value: Any

class MissingValueError(DaciteFieldError):
    """Raised when a required field is missing from the input data."""

class UnionMatchError(WrongTypeError):
    """Raised when a value cannot match any type in a union."""

class StrictUnionMatchError(DaciteFieldError):
    """
    Raised when multiple union types match in strict mode.
    
    Attributes:
        union_matches: Dictionary of matching types and their converted values
    """
    union_matches: Dict[Type, Any]

class ForwardReferenceError(DaciteError):
    """
    Raised when forward references cannot be resolved.
    
    Attributes:
        message: Error message describing the resolution failure
    """
    message: str

class UnexpectedDataError(DaciteError):
    """
    Raised when strict mode encounters unexpected fields in the input data.
    
    Attributes:
        keys: Set of unexpected field names
    """
    keys: Set[str]

Advanced Features

Nested Structures

Automatically converts nested dictionaries to nested dataclasses:

@dataclass
class Address:
    street: str
    city: str

@dataclass
class Person:
    name: str
    address: Address

data = {
    "name": "John",
    "address": {
        "street": "123 Main St",
        "city": "Anytown"
    }
}

person = from_dict(Person, data)

Union Types and Optional Fields

Supports complex type annotations including unions and optional fields:

from typing import Union, Optional

@dataclass
class FlexibleData:
    value: Union[str, int, float]
    optional_field: Optional[str] = None

data = {"value": 42}  # optional_field will be None
result = from_dict(FlexibleData, data)

Collections and Generics

Handles lists, tuples, sets, dictionaries, and generic types:

from typing import List, Dict

@dataclass
class Container:
    items: List[str]
    mapping: Dict[str, int]

data = {
    "items": ["a", "b", "c"],
    "mapping": {"x": 1, "y": 2}
}

container = from_dict(Container, data)

Custom Type Hooks

Transform values during conversion using type hooks:

from datetime import datetime

def parse_datetime(value):
    return datetime.fromisoformat(value)

@dataclass
class Event:
    name: str
    timestamp: datetime

config = Config(type_hooks={datetime: parse_datetime})
data = {"name": "Meeting", "timestamp": "2023-01-01T10:00:00"}
event = from_dict(Event, data, config)

Types

from typing import Protocol, Any, TypeVar, Type, Optional, Dict, Callable, List, Set

T = TypeVar("T")

class Data(Protocol):
    """
    Protocol defining the interface for input data objects.
    Any dictionary-like object that supports these methods can be used.
    """
    def keys(self) -> Any: ...
    def __getitem__(self, *args, **kwargs) -> Any: ...
    def __contains__(self, *args, **kwargs) -> bool: ...

Install with Tessl CLI

npx tessl i tessl/pypi-dacite
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/dacite@1.9.x
Publish Source
CLI
Badge
tessl/pypi-dacite badge