The CLI Tool¶
The wiz
command provides a companion CLI tool for the Dataclass Wizard,
which further simplifies interaction with the Python dataclasses
module.
Getting help:
$ wiz -h
usage: wiz [-h] [-V] {gen-schema,gs} ...
A companion CLI tool for the Dataclass Wizard, which simplifies interaction with the Python `dataclasses` module.
positional arguments:
{gen-schema,gs} Supported sub-commands
gen-schema (gs)
Generates a Python dataclass schema, given a JSON input.
optional arguments:
-h, --help show this help message and exit
-V, --version Display the version of this tool.
Checking the version of the CLI tool should display the currently installed
version of the dataclass-wizard
library:
$ wiz -V
To get help on a subcommand, simply use wiz <subcommand> -h
. For example:
$ wiz gs -h
JSON To Dataclass Generation Tool¶
The subcommand gen-schema
(aliased to gs
) provides a JSON to Python
schema generation tool. This utility takes a JSON file or string as an input,
and outputs the corresponding dataclass schema. The main purpose is to easily
create dataclasses that can be used with API output, without resorting to
dict
’s or NamedTuple
’s.
This scheme generation tool is inspired by the following projects:
Note
A few things to consider:
The script sometimes has to make some assumptions, so give the output a once-over.
In an array of objects (i.e. dictionaries), all key names and type definitions get merged into a single model
dataclass
, as the objects are considered homogenous in this case.Deeply nested lists within objects (e.g. list -> dict -> list) should similarly merge all list elements with the other lists under that key in each sibling dict object.
The output is properly formatted, including additional spacing where needed. Please consider opening an issue if there are any potential improvements to be made.
Example usage:
echo '{
"name": "Yavin IV",
"rotation_period": "24",
"orbital_period": "4818",
"diameter": "10200",
"climate": "temperate, tropical",
"gravity": "1 standard",
"terrain": "jungle, rainforests",
"surface_water": "8",
"population": "1000",
"residents": [],
"films": [
"https://swapi.co/api/films/1/"
],
"created": "2014-12-10T11:37:19.144000Z",
"edited": "2014-12-20T20:58:18.421000Z",
"url": "https://swapi.co/api/planets/3/"
}' | wiz gs
Generates the following Python code:
from dataclasses import dataclass
from datetime import datetime
from typing import List, Union
@dataclass
class Data:
"""
Data dataclass
"""
name: str
rotation_period: Union[int, str]
orbital_period: Union[int, str]
diameter: Union[int, str]
climate: str
gravity: str
terrain: str
surface_water: Union[int, str]
population: Union[int, str]
residents: List
films: List[str]
created: datetime
edited: datetime
url: str
Note: to write the output to a Python file instead of displaying the
output in the terminal, pass the name of the output file. If the file
has no extension, a default .py
extension will be added.
For example:
# Note: the following command writes to a new file 'out.py'
echo '<json string>' | wiz gs - out
Future Annotations¶
Passing in the -x/--experimental
flag will enable experimental features via
a __future__
import, which allows PEP 585 and PEP 604- style
annotations to be used in Python 3.7+
For example, assume your input.json
file contains the following contents:
{
"myField": null,
"My_List": [],
"Objects": [
{
"key1": false
},
{
"key1": 1.2,
"key2": "string"
},
{
"key1": "val",
"key2": null
}
]
}
Then we could run the following command:
$ wiz gs -x input.json
The generated Python code is slightly different, as shown below. You might notice
that a __future__
import is added at the top, for compatibility with versions
earlier than Python 3.10. In the annotations, we also prefer to use parameterized
standard collections, and use the new pipe |
syntax to represent Union
and Optional
types.
from __future__ import annotations
from dataclasses import dataclass
from typing import Any
from dataclass_wizard import JSONWizard
@dataclass
class Data(JSONWizard):
"""
Data dataclass
"""
my_field: Any
my_list: list
objects: list[Object]
@dataclass
class Object:
"""
Object dataclass
"""
key1: bool | float | str
key2: str | None