def dump(self): """ Convert the object to a JSON dictionary, so that every entry is serialized. Uses the json encoder client, so objects with uids are converted to LinkByUID dictionaries. Returns ------- str A string representation of the object as a dictionary. """ from taurus.json import TaurusJson encoder = TaurusJson() return json.loads(encoder.raw_dumps(self))
def test_thin_dumps(): """Test that thin_dumps turns pointers into links.""" mat = MaterialRun("The actual material") meas_spec = MeasurementSpec("measurement", uids={'my_scope': '324324'}) meas = MeasurementRun("The measurement", spec=meas_spec, material=mat) thin_copy = MeasurementRun.build(json.loads(TaurusJson().thin_dumps(meas))) assert isinstance(thin_copy, MeasurementRun) assert isinstance(thin_copy.material, LinkByUID) assert isinstance(thin_copy.spec, LinkByUID) assert thin_copy.spec.id == meas_spec.uids['my_scope'] # Check that LinkByUID objects are correctly converted their JSON equivalent expected_json = '{"id": "my_id", "scope": "scope", "type": "link_by_uid"}' assert TaurusJson().thin_dumps(LinkByUID('scope', 'my_id')) == expected_json # Check that objects lacking .uid attributes will raise an exception when dumped with pytest.raises(TypeError): TaurusJson().thin_dumps({{'key': 'value'}})
def test_deserialize(): """Round-trip serde should leave the object unchanged.""" condition = Condition(name="A condition", value=NominalReal(7, '')) parameter = Parameter(name="A parameter", value=NormalReal(mean=17, std=1, units='')) measurement = MeasurementRun(tags="A tag on a measurement", conditions=condition, parameters=parameter) copy_meas = TaurusJson().copy(measurement) assert(copy_meas.conditions[0].value == measurement.conditions[0].value) assert(copy_meas.parameters[0].value == measurement.parameters[0].value) assert(copy_meas.uids["auto"] == measurement.uids["auto"])
def test_register_argument_validation(): """Test that register_classes argument is type checked.""" orig = TaurusJson() with pytest.raises(ValueError): orig.register_classes("foo") with pytest.raises(ValueError): orig.register_classes({"foo": orig}) with pytest.raises(ValueError): orig.register_classes({ProcessSpec: ProcessSpec})
def build(d): """ Build an object from a JSON dictionary. This differs from `from_dict` in that the values themselves may *also* be dictionaries corresponding to serialized DictSerializable objects. Parameters ---------- d: dict The object as a serialized dictionary. Returns ------- DictSerializable The deserialized object. """ from taurus.json import TaurusJson encoder = TaurusJson() return encoder.raw_loads(encoder.raw_dumps(d))
def test_register_classes_override(): """Test that register_classes overrides existing entries in the class index.""" class MyProcessSpec(ProcessSpec): pass normal = TaurusJson() custom = TaurusJson() custom.register_classes({MyProcessSpec.typ: MyProcessSpec}) obj = ProcessSpec(name="foo") assert not isinstance(normal.copy(obj), MyProcessSpec),\ "Class registration bled across TaurusJson() objects" assert isinstance(custom.copy(obj), ProcessSpec),\ "Custom TaurusJson didn't deserialize as MyProcessSpec"
def test_pure_subsitutions(): """Make sure substitute methods don't mutate inputs.""" json_str = ''' [ [ { "uids": { "id": "9118c2d3-1c38-47fe-a650-c2b92fdb6777" }, "type": "material_run", "name": "flour" } ], { "type": "ingredient_run", "uids": { "id": "8858805f-ec02-49e4-ba3b-d784e2aea3f8" }, "material": { "type": "link_by_uid", "scope": "ID", "id": "9118c2d3-1c38-47fe-a650-c2b92fdb6777" }, "process": { "type": "link_by_uid", "scope": "ID", "id": "9148c2d3-2c38-47fe-b650-c2b92fdb6777" } } ] ''' index = {} original = json.loads(json_str, object_hook=lambda x: TaurusJson()._load_and_index(x, index)) frozen = deepcopy(original) loaded = substitute_objects(original, index) assert original == frozen frozen_loaded = deepcopy(loaded) substitute_links(loaded) assert loaded == frozen_loaded for o in loaded: substitute_links(o) assert loaded == frozen_loaded
lambda obj: obj.uids or obj.add_uid(DEMO_SCOPE, obj.name + run_key)) cake.notes = cake.notes + "; Très délicieux! 😀" cake.file_links = [ FileLink( filename="Photo", url='https://www.landolakes.com/RecipeManagementSystem/media/' 'Recipe-Media-Files/Recipes/Retail/x17/16730-beckys-butter-cake-600x600.jpg?ext=.jpg' ) ] return cake if __name__ == "__main__": encoder = TaurusJson() cake = make_cake(seed=42) with open("example_taurus_material_history.json", "w") as f: context_list = complete_material_history(cake) f.write(json.dumps(context_list, indent=2)) with open("example_taurus_material_template.json", "w") as f: f.write(encoder.thin_dumps(cake.template, indent=2)) with open("example_taurus_process_template.json", "w") as f: f.write( encoder.thin_dumps( cake.process.ingredients[0].material.process.template, indent=2))
def test_enumeration_serde(): """An enumeration should get serialized as a string.""" condition = Condition(name="A condition", notes=Origin.UNKNOWN) copy_condition = TaurusJson().copy(condition) assert copy_condition.notes == Origin.get_value(condition.notes)
def copy(obj): return TaurusJson().copy(obj)
def raw_loads(json_str, **kwargs): return TaurusJson().raw_loads(json_str, **kwargs)
def thin_dumps(obj, **kwargs): return TaurusJson().thin_dumps(obj, **kwargs)
def raw_dumps(obj, **kwargs): return TaurusJson().raw_dumps(obj, **kwargs)