Overview¶
Requirements¶
The dataclass-wizard
library officially supports Python 3.6+
There are no core requirements outside of the Python standard library. That being said, this library does utilize a few conditional dependencies:
typing-extensions - this is a lightweight and highly useful library that backports the most recently added features to the
typing
module. For more info, check out the Py Compatibility section.dataclasses - a backport of the
dataclasses
module for Python 3.6backports-datetime-fromisoformat - a backport of fromisoformat() for Python 3.6
Advantages¶
Minimal setup required. In most cases, all you need is a dataclass that sub-classes from
JSONWizard
.Speed. It is up to 25 times faster than libraries such as dataclasses-json that use
marshmallow
, and about 60 x faster than libraries such as jsons which don’t seem to handle dataclasses as well as you’d expect.Adds the ability to use field properties (with default values) in dataclasses.
Automatic key transform to/from JSON (ex. camel to snake). Custom key mappings also supported.
Automatic type conversion when loading from JSON or a
dict
object. For instance, strings are converted to boolean if a type annotation isList[bool]
.Built-in support for standard Python collections, as well as most Generics from the
typing
module. Other commonly used types such as Enums, defaultdict, and date and time objects such asdatetime
are also natively supported.Latest Python features such as parameterized standard collections can be used.
Ability to construct ad-hoc dataclass schemas using JSON input (either as a file or string) using the included wiz-cli utility.
Supported Types¶
Tip
See the below section on Special Cases for additional info on the JSON load/dump process for special Python types.
- Strings
str
bytes
bytearray
- Numerics
int
float
Decimal
Booleans (
bool
)- Sequences (and their equivalents in the
typing
module) list
deque
tuple
NamedTuple
- Sequences (and their equivalents in the
- Sets (and their equivalents in the
typing
module) set
frozenset
- Sets (and their equivalents in the
- Mappings (and their equivalents in the
typing
module) dict
defaultdict
TypedDict
OrderedDict
- Mappings (and their equivalents in the
Enum
subclassesUUID
- date and time objects
datetime
date
time
timedelta
- Special typing primitives from the
typing
module Any
Union
- Also supports using dataclasses.Optional
- Special typing primitives from the
Recently introduced Generic types (available in Python 3.6+ via the
typing-extensions
module)Annotated
Literal
Special Cases¶
Note
With most annotated Python types, it is clear and unambiguous how they are to be loaded from JSON, or dumped when they are serialized back to JSON.
However, here a few special cases that are worth going over.
bool
- JSON values that appear as strings or integers will be de-serialized to abool
using a case-insensitive search that matches against the following “truthy” values:TRUE, T, YES, Y, 1
Enum
- JSON values (ideally strings) are de-serialized toEnum
subclasses via thevalue
attribute, and are serialized back to JSON using the samevalue
attribute.UUID
types are de-serialized from JSON strings using the constructor method – i.e.UUID(string)
, and by default are serialized back to JSON using thehex
attribute – i.e.my_uuid.hex
.Decimal
types are de-serialized using theDecimal(str(o))
syntax – or via an annotated subclass of Decimal – and are serialized via the builtinstr()
function.NamedTuple
sub-types are de-serialized from alist
,tuple
, or any iterable type into the annotated sub-type. They are serialized back as the the annotatedNamedTuple
sub-type; this is mainly because named tuples are essentially just tuples, so they are inherently JSON serializable to begin with.For
date
,time
, anddatetime
types, string values are de-serialized using the builtinfromisoformat()
method; fordatetime
andtime
types, a suffix of “Z” appearing in the string is first replaced with “+00:00”, which represents UTC time. JSON values fordatetime
anddate
annotated types appearing as numbers will be de-serialized using the builtinfromtimestamp()
method.All these types are serialized back to JSON using the builtin
isoformat()
method. Fordatetime
andtime
types, there is one noteworthy addition: the suffix “+00:00” is replaced with “Z”, which is a common abbreviation for UTC time.For
timedelta
types, the values to de-serialize can either be strings or numbers, so we check the type explicitly. If the value is a string, we first ensure it’s in a numeric form like ‘1.23’, and if so convert it to a float value in seconds; otherwise, we convert values like ‘01:45’ or ‘3hr12m56s’ via the pytimeparse module, which is also available as an extra viapip install dataclass-wizard[timedelta]
. Lastly, any numeric values are assumed to be in seconds and are used as is.All
timedelta
values are serialized back to JSON using the builtinstr()
method, so for exampletimedelta(seconds=3)
will be serialized as “0:00:03”.set
,frozenset
, anddeque
types will be de-serialized using their annotated base types, and serialized aslist
’s.Commonly used
dict
sub-types (such asdefaultdict
) will be de-serialized from JSON objects using the annotated base type, and serialized back as plaindict
objects.