Examples¶
Class inheritance and migrations¶
By default nme uses migrations of parent class if defined:
Lets see this code sample:
import json
from datetime import date
from pydantic import BaseModel
from nme import NMEEncoder
class Person(BaseModel):
name: str
birth_date: date
class Employee(Person):
company: str
data = Employee(name="John Smith", birth_date=date(1980, 1, 15), company="Nme")
with open("employee.json", "w") as f:
json.dump(data, f, cls=NmeEncoder)
Assume that one would like to split Person.name into
two fields: names and last_name.
Also there is a need to load data from previous version. Following code will do it:
import json
from datetime import date
from pydantic import BaseModel
from nme import nme_object_hook, register_class
def _migrate_person(dkt):
dkt = dict(dkt) # copy for safety
name_list = dkt["name"].rsplit(" ", 1)
if len(name_list) == 1:
dkt["names"] = name_list[0]
dkt["last_name"] = ""
else:
dkt["names"], dkt["last_name"] = name_list
return dkt
@register_class("0.0.1", migrations=[("0.0.1", _migrate_person)])
class Person(BaseModel):
names: str
last_name: str
birth_date: date
class Employee(Person):
company: str
data = Employee(names="John", last_name="Smith", birth_date=date(1980, 1, 15), company="Nme")
with open("employee.json",) as f:
data2 = json.load(f, object_hook=nme_object_hook)
assert data == data2
register_class()has ause_parent_migrationsargument bydefault set to
True. If set toFalse, parents class migration will be ignored. This may be usefully in some rare examples, when fixing old data structures.
update_argument¶
The nme.update_argument() is a helper function that allow update
the dict argument of a function to class based
(for example pydantic.BaseModel based)
keeping backward compatibility.
Lets have function:
from typing import Dict
def my_function(arg: Dict[str, int]):
return arg.get("a", 1) + arg.get("b", 2)
assert my_function({"a":5}) == 7
And assume that we would like to use nme for serialize argument of this
function and have option to use migration engine.
To keep backward compatibility we can wrote following code:
from typing import Dict
from pydantic import BaseModel
from nme import update_argument
class MyArgument(BaseModel):
a: int = 1
b: int = 2
@update_argument("arg")
def my_function(arg: MyArgument):
return arg.a + arg.b
assert my_function({"a":5}) == 7
assert my_function(MyArgument(a=5)) == 7
update_argument use inspect module to
determine argument class.
CBOR support¶
cbor2 encoder (nme_object_encoder) and object hook
(nme_cbor_decoder) are available.
import cbor2
from pydantic import BaseModel
from nme import nme_cbor_encoder, nme_cbor_decoder
class SampleModel(BaseModel):
field1: int
field2: str
data = SampleModel(field1=4, field2="abc")
with open("sample.cbor", "wb") as f_p:
cbor2.dump(data, f_p, default=nme_cbor_encoder)
with open("sample.cbor", "rb") as f_p:
data2 = cbor2.load(f_p, object_hook=nme_cbor_decoder)
assert data == data2