Serialization

Basics

EPyT-Flow comes with a custom binary serialization mechanism that allows the user to load and save almost any EPyT-Flow class to/from a file or byte array. This allows an easy and fast storing/loading & sharing of configurations and results.

The implemented serialization mechanism is based on MessagePack and is enriched with gzip compression.

Every serializable EPyT-Flow class supports the following functions:

Function

Description

dump()

Exports instance to byte array

load()

Creates instance from byte array

save_to_file()

Exports instance into a file

load_from_file()

Creates instance from file

Example for exporting and importing a sensor configuration to/from a byte array:

# Open/Create a new scenario based on the Hanoi network
network_config = load_hanoi()
with ScenarioSimulator(scenario_config=network_config) as sim:
    # Create sensor placement ...

    # Export sensor config to byte array
    sensor_config_data = sim.sensor_config.dump()

    # ...

    # Load sensor config from byte array
    my_sensor_config = SensorConfig.load(sensor_config_data)
    print(my_sensor_config == sim.sensor_config)    # True

Example for storing and loading a scenario configuration to/from a file:

# Create scenario configuration
config = load_hanoi()

# Store in a file
config.save_to_file("myHanoiConfig.epytflow_config")

# ...

# Load scenario configuration from file
my_config = ScenarioConfig.load_from_file("myHanoiConfig.epytflow_config")

JSON

Besides the custom binary serialization, many EPyT-Flow classes also support a JSON serialization – i.e. instances of such classes can be loaded/stored from/to JSON. Such classes are derived from JsonSerializable which itself is a sub-clas of Serializable.

Classes supporting JSON serialization provide the following additional methods:

Function

Description

to_json()

Exports this instance to JSON

load_from_json()

Creates instance from JSON

load_from_json_file()

Creates instance from a JSON files

save_to_json_file()

Exports instance into a JSON file

Advanced

To make any new class (e.g. custom events) serializable, the class must be derived from Serializable and be marked by the serializable() decorator.

Any class derived from Serializable must implement the get_attributes() method. This method is supposed to return a dictionary of the attributes completely describing the instance – those will be passed to the constructor when deserializing an instance of this class.

The serializable() decorator requires a unique ID of the class that is made serializable – i.e. every class (more generally every data type) is assigned a unique ID to make it recognizable by the parser. All reserved IDs (you CANNOT use those!) are listed in epyt_flow.serialization.py – right now any number greater than 30 is free for use. Furthermore, a file extension is required which should allow the user to infer the type of content – this file extension is appended to the path automatically, if not already present.

Example of making a new class MyClass serializable – this class is assigned the ID 42:

@serializable(42, ".my_file_ext")
class MyNewClass(Serializable):
    def __init__(self, my_var_1, my_var_2, **kwds):
        self.my_var_1 = my_var_1
        self.my_var_2 = my_var_2

        # Other initialization logic ...

        super().__init__(**kwds)

    def get_attributes(self) -> dict:
        return super().get_attributes() | \
            {"my_var_1": self.my_var_1, "my_var_2": self.my_var_2}

    # Other class methods ...