Data Type Definition
Structured data in JSONClasses are defined with Python class syntax and type hint.
#
The Decorated ClassDefining your data with JSONClasses is rather simple.
@jsonclassclass Cat: name: str birthday: date weight: float
Declare a normal Python class, with magical @jsonclass
decorator. There you get full power of JSONClasses.
tom = Cat(name='Tom', birthday='2020-08-31', weight=5.4)
#
Default ValueYou can specify default value on class definition.
@jsonclassclass Dog: name: str age: int is_sold: bool = false buyer_name: Optional[str]
Therefore, on object creation, a default value will be assigned if it's not provided.
buddy = Dog(name='Buddy', age=1)
#
Primitive Data TypesJSONClasses supports str
, int
, float
, bool
, date
and datetime
.
@jsonclassclass MyObject: str_value: str int_value: int float_value: float bool_value: bool date_value: date datetime_value: datetime
#
EnumEnum is handy when defining a field with predictable limited amount of choices. Define enum in JSONClasses requires two steps just like in Python.
@jsonenumclass Sex(Enum): MALE = 1 FEMALE = 2
@jsonclassclass Dog: name: str sex: Sex age: int
To create an object with enum values, you can pass its capitalized name as value by default. You can tweak this behavior with types
marker introduced in this guide.
buddy = Dog(name='Buddy', sex='MALE', age=1)
#
Collection TypesJSONClasses supports collection types list
and dict
. You can nest them anyway you'd like.
@jsonclassclass MyObject: list_value: list[str] dict_value: dict[str, int] nested_dict_in_list_value: list[dict[str, str]] nested_list_in_dict_value: dict[str, list[int]]
#
Optional TypeYou can define optional type with Optional
type annotation.
@jsonclassclass User: username: str email: str invitation_code: Optional[str]
#
Embedded Object TypesJSONClasses objects can have other JSONClasses objects as their field values.
@jsonclassclass ShippingAddress: line1: str line2: Optional[str] city: str country: str postal_code: str
@jsonclassclass User: username: str shipping_addresses: list[ShippingAddress]
#
Linked Object TypesOn an object graph, objects are linked with each other. JSONClasses utilizes Python's Annotated
type hint to declare link relationships right in type definitions.
@jsonclassclass Article: title: str content: str author: Annotated[Author, linkto]
@jsonclassclass Author: name: str articles: Annotated[list[Article], linkedby('author')]
Link relationships are categorized into 3: 1-to-1, 1-to-many and many-to-many.
An 1-to-1 link relationship is declared with 1 side linkto
and 1 side linkedby
.
An 1-to-many link relationship is also declared with 1 side linkto
and 1 side linkedby
, while the declared type with linkedby
is a JSONClasses object list of a specified class.
A many-to-many link relationship can be declared with 1 side linkto
and 1 side linkedby
. It can also be declared with double side linkedthru
depends on how you persist your data in the database. The field type must be a JSONClasses object list type.
#
Types ModifiersA simple type hint won't satisfy complex data validation and transformation needs. This is where types modifier comes in.
We specify other types information with an unintuitive yet innovative equal sign.
@jsonclassclass User: username: str = types.str.required email: Optional[str] = types.str.email password: str = types.writeonly.str.transform(salt).required articles: list[Article] = types.listof('Article').linkedby('author').required created_at: datetime = types.readonly.datetime.tscreated.required updated_at: datetime = types.readonly.datetime.tsupdated.required
For a complete list of available types modifiers, please visit API Documentation: Types Modifiers.
#
ORM Integrated ModelsYou can turn a existing JSONClasses class into ORM model definition by adding yet another magical decorator. These decorators are provided through additional packages.
@pymongo@jsonclassclass User: id: str = types.readonly.str.primary.mongoid.required email: Optional[str] = types.str.email password: str = types.writeonly.str.transform(salt).required articles: list[Article] = types.listof('Article').linkedby('author').required created_at: datetime = types.readonly.datetime.tscreated.required updated_at: datetime = types.readonly.datetime.tsupdated.required