Usage

Basics

A simple example models two Person objects in a Car.

from dataclasses import dataclass

# Or using attrs
# from attr import dataclass

from typing import List

import desert

@dataclass
class Person:
    name: str
    age: int

@dataclass
class Car:
    passengers: List[Person]

# Load some simple data types.
data = {'passengers': [{'name': 'Alice', 'age': 21}, {'name': 'Bob', 'age': 22}]}


# Create a schema for the Car class.
schema = desert.schema(Car)

# Load the data.
car = schema.load(data)
assert car == Car(passengers=[Person(name='Alice', age=21), Person(name='Bob', age=22)])

Desert can be used with dataclasses or attr. With either module, Desert is able to infer the appropriate marshmallow field for any of these types:

There are two syntaxes for specifying a field.

In the more concise form, desert.field() wraps dataclasses.field() and desert.ib() wraps attr.ib(). These functions take a marshmallow.fields.Field as the first argument, and the remaining arguments are forwarded to the corresponding wrapped function.

In the more verbose form, simply use the normal functions dataclasses.field() and attr.ib(), but provide the metadata value using desert.metadata(), which returns a dict of values namespaced for desert to use.

Use with dataclasses

import dataclasses
import datetime

import desert
import marshmallow


@dataclasses.dataclass
class Entry:

    timestamp: str = desert.field(marshmallow.fields.NaiveDateTime())

    # Or use the more verbose form.
    favorite_number: int = dataclasses.field(default=3, metadata=desert.metadata(field=marshmallow.fields.Int()))

schema = desert.schema(Entry)

print(schema.load({"timestamp": "2019-10-21T10:25:00", "favorite_number": 42}))
Entry(timestamp=datetime.datetime(2019, 10, 21, 10, 25), favorite_number=42)

Use with attrs

import datetime

import attr
import desert
import marshmallow


@attr.dataclass
class Entry:

    timestamp: str = desert.ib(marshmallow.fields.NaiveDateTime())

    # Or use the more verbose form.
    favorite_number: int = attr.ib(default=3, metadata=desert.metadata(field=marshmallow.fields.Int()))

schema = desert.schema(Entry)

print(schema.load({"timestamp": "2019-10-21T10:25:00", "favorite_number": 42}))
Entry(timestamp=datetime.datetime(2019, 10, 21, 10, 25), favorite_number=42)

Schema meta parameters

Any marshmallow.Schema.Meta value is accepted in the meta dict. For example, to exclude unknown values during deserialization:

import attr
import desert

@attr.dataclass
class A:
    x: int

schema = desert.schema_class(A, meta={"unknown": marshmallow.EXCLUDE})()
print(schema.load({"x": 1, "y": 2}))
A(x=1)